blob: 897efb0e24521a3781feaa3cb6e098f79c740714 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
package tasks
import (
"sync"
"github.com/jesseduffield/lazygit/pkg/utils"
)
// the purpose of an AsyncHandler is to ensure that if we have multiple long-running
// requests, we only handle the result of the latest one. For example, if I am
// searching for 'abc' and I have to type 'a' then 'b' then 'c' and each keypress
// dispatches a request to search for things with the string so-far, we'll be searching
// for 'a', 'ab', and 'abc', and it may be that 'abc' comes back first, then 'ab',
// then 'a' and we don't want to display the result for 'a' just because it came
// back last. AsyncHandler keeps track of the order in which things were dispatched
// so that we can ignore anything that comes back late.
type AsyncHandler struct {
currentId int
lastId int
mutex sync.Mutex
onReject func()
}
func NewAsyncHandler() *AsyncHandler {
return &AsyncHandler{
mutex: sync.Mutex{},
}
}
func (self *AsyncHandler) Do(f func() func()) {
self.mutex.Lock()
self.currentId++
id := self.currentId
self.mutex.Unlock()
go utils.Safe(func() {
after := f()
self.handle(after, id)
})
}
// f here is expected to be a function that doesn't take long to run
func (self *AsyncHandler) handle(f func(), id int) {
self.mutex.Lock()
defer self.mutex.Unlock()
if id < self.lastId {
if self.onReject != nil {
self.onReject()
}
return
}
self.lastId = id
f()
}
|