summaryrefslogtreecommitdiffstats
path: root/pkg/tasks
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2021-10-18 19:00:03 +1100
committerJesse Duffield <jessedduffield@gmail.com>2021-10-19 09:02:42 +1100
commitca7252ef8ee26affdc2c74f05c9c20196a8d571b (patch)
tree7323ca472558a435f01ae62e123cc2576e1959b3 /pkg/tasks
parenta496858c629e3c6241b51cf99cd38d6fa1b787bc (diff)
suggest files when picking a path to filter on
async fetching of suggestions remove limit cache the trie for future use more more
Diffstat (limited to 'pkg/tasks')
-rw-r--r--pkg/tasks/async_handler.go56
-rw-r--r--pkg/tasks/async_handler_test.go44
2 files changed, 100 insertions, 0 deletions
diff --git a/pkg/tasks/async_handler.go b/pkg/tasks/async_handler.go
new file mode 100644
index 000000000..897efb0e2
--- /dev/null
+++ b/pkg/tasks/async_handler.go
@@ -0,0 +1,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()
+}
diff --git a/pkg/tasks/async_handler_test.go b/pkg/tasks/async_handler_test.go
new file mode 100644
index 000000000..b6edbec20
--- /dev/null
+++ b/pkg/tasks/async_handler_test.go
@@ -0,0 +1,44 @@
+package tasks
+
+import (
+ "fmt"
+ "sync"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAsyncHandler(t *testing.T) {
+ wg := sync.WaitGroup{}
+ wg.Add(2)
+
+ handler := NewAsyncHandler()
+ handler.onReject = func() {
+ wg.Done()
+ }
+
+ result := 0
+
+ wg2 := sync.WaitGroup{}
+ wg2.Add(1)
+
+ handler.Do(func() func() {
+ wg2.Wait()
+ return func() {
+ fmt.Println("setting to 1")
+ result = 1
+ }
+ })
+ handler.Do(func() func() {
+ return func() {
+ fmt.Println("setting to 2")
+ result = 2
+ wg.Done()
+ wg2.Done()
+ }
+ })
+
+ wg.Wait()
+
+ assert.EqualValues(t, 2, result)
+}