mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-13 11:57:33 -04:00
Merge pull request #1302 from aduffeck/debouncer
Do not run the timout func if the work func has run
This commit is contained in:
@@ -24,7 +24,7 @@ type workItem struct {
|
||||
t *time.Timer
|
||||
timeout *time.Timer
|
||||
|
||||
trigger func()
|
||||
work func()
|
||||
}
|
||||
|
||||
type AckFunc func() error
|
||||
@@ -54,7 +54,8 @@ func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId, ack AckFunc) {
|
||||
return
|
||||
}
|
||||
|
||||
trigger := func() {
|
||||
wi := &workItem{}
|
||||
wi.work = func() {
|
||||
if _, ok := d.inProgress.Load(id.OpaqueId); ok {
|
||||
// Reschedule this run for when the previous run has finished
|
||||
d.mutex.Lock()
|
||||
@@ -66,9 +67,12 @@ func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId, ack AckFunc) {
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
wi.timeout.Stop() // stop the timeout timer if it is running
|
||||
delete(d.pending, id.OpaqueId)
|
||||
d.inProgress.Store(id.OpaqueId, true)
|
||||
defer d.inProgress.Delete(id.OpaqueId)
|
||||
defer func() {
|
||||
d.inProgress.Delete(id.OpaqueId)
|
||||
}()
|
||||
d.mutex.Unlock() // release the lock early to allow other goroutines to debounce
|
||||
|
||||
d.f(id)
|
||||
@@ -80,16 +84,13 @@ func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId, ack AckFunc) {
|
||||
}
|
||||
}()
|
||||
}
|
||||
t := time.AfterFunc(d.after, trigger)
|
||||
wi.t = time.AfterFunc(d.after, wi.work)
|
||||
wi.timeout = time.AfterFunc(d.timeout, func() {
|
||||
d.log.Debug().Msg("timeout while waiting for space debouncer to finish")
|
||||
wi.t.Stop()
|
||||
wi.work()
|
||||
})
|
||||
|
||||
d.pending[id.OpaqueId] = &workItem{
|
||||
trigger: trigger,
|
||||
t: t,
|
||||
timeout: time.AfterFunc(d.timeout, func() {
|
||||
d.log.Debug().Msg("timeout while waiting for space debouncer to finish")
|
||||
t.Stop()
|
||||
trigger()
|
||||
}),
|
||||
}
|
||||
d.pending[id.OpaqueId] = wi
|
||||
|
||||
}
|
||||
|
||||
@@ -115,6 +115,26 @@ var _ = Describe("SpaceDebouncer", func() {
|
||||
}, "300ms").Should(Equal(1))
|
||||
})
|
||||
|
||||
It("doesn't run the timeout function if the work function has been called", func() {
|
||||
debouncer = search.NewSpaceDebouncer(100*time.Millisecond, 250*time.Millisecond, func(id *sprovider.StorageSpaceId) {
|
||||
if id.OpaqueId == "spaceid" {
|
||||
callCount.Add(1)
|
||||
}
|
||||
}, log.NewLogger())
|
||||
|
||||
// Initial call to start the timers
|
||||
debouncer.Debounce(spaceid, nil)
|
||||
|
||||
// Wait for the debounce timer to fire
|
||||
Eventually(func() int {
|
||||
return int(callCount.Load())
|
||||
}, "200ms").Should(Equal(1))
|
||||
|
||||
// The timeout function should not be called
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
Expect(int(callCount.Load())).To(Equal(1))
|
||||
})
|
||||
|
||||
It("calls the ack function when the debounce fires", func() {
|
||||
var ackCalled atomic.Bool
|
||||
ackFunc := func() error {
|
||||
|
||||
Reference in New Issue
Block a user