mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-12 11:15:00 +02:00
57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
|
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()
|
||
|
}
|