Skip to content

Commit f1527dd

Browse files
authored
Merge pull request #24 from vnteamopen/fix-done-channel
Fix done channel
2 parents ab8103a + 8157702 commit f1527dd

2 files changed

Lines changed: 49 additions & 8 deletions

File tree

debouncer.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type Debouncer struct {
1515

1616
// New creates a new instance of debouncer. Each instance of debouncer works independent, concurrency with different wait duration.
1717
func New(duration time.Duration) *Debouncer {
18-
return &Debouncer{timeDuration: duration, triggeredFunc: func() {}, done: make(chan struct{})}
18+
return &Debouncer{timeDuration: duration, triggeredFunc: func() {}}
1919
}
2020

2121
// WithTriggered attached a triggered function to debouncer instance and return the same instance of debouncer to use.
@@ -32,7 +32,8 @@ func (d *Debouncer) SendSignal() {
3232
d.Cancel()
3333
d.timer = time.AfterFunc(d.timeDuration, func() {
3434
d.triggeredFunc()
35-
d.done <- struct{}{}
35+
close(d.done)
36+
d.done = make(chan struct{})
3637
})
3738
}
3839

@@ -47,20 +48,22 @@ func (d *Debouncer) Cancel() {
4748
if d.timer != nil {
4849
d.timer.Stop()
4950
}
50-
d.done = make(chan struct{})
5151
}
5252

5353
// UpdateTriggeredFunc replaces triggered function.
5454
func (d *Debouncer) UpdateTriggeredFunc(newTriggeredFunc func()) {
5555
d.triggeredFunc = newTriggeredFunc
5656
}
5757

58-
// UpdateTimeDuratioe replaces the waiting time duration. You need to call a SendSignal() again to trigger a new timer with a new waiting time duration.
58+
// UpdateTimeDuration replaces the waiting time duration. You need to call a SendSignal() again to trigger a new timer with a new waiting time duration.
5959
func (d *Debouncer) UpdateTimeDuration(newTimeDuration time.Duration) {
6060
d.timeDuration = newTimeDuration
6161
}
6262

6363
// Done returns a receive-only channel to notify the caller when the triggered func has been executed.
6464
func (d *Debouncer) Done() <-chan struct{} {
65+
if d.done == nil {
66+
d.done = make(chan struct{})
67+
}
6568
return d.done
6669
}

debouncer_test.go

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,55 @@ func TestDone(t *testing.T) {
216216
debouncer := godebouncer.New(200 * time.Millisecond).WithTriggered(incrementCount)
217217
expectedCounter := int(2)
218218

219-
fmt.Println("Action 1")
220219
debouncer.SendSignal()
221-
time.Sleep(400 * time.Millisecond)
220+
<-debouncer.Done()
221+
222+
debouncer.SendSignal()
223+
<-debouncer.Done()
224+
225+
if *countPtr != expectedCounter {
226+
t.Errorf("Expected count %d, was %d", expectedCounter, *countPtr)
227+
}
228+
}
229+
230+
func TestDoneInGoroutine(t *testing.T) {
231+
countPtr, incrementCount := createIncrementCount(0)
232+
debouncer := godebouncer.New(200 * time.Millisecond).WithTriggered(incrementCount)
233+
expectedCounter := int(3)
222234

223-
fmt.Println("Action 2")
224235
debouncer.SendSignal()
236+
go func() {
237+
<-debouncer.Done() // awaits for the second send signal to complete
238+
*countPtr += 2
239+
}()
240+
241+
debouncer.SendSignal() // after 1 milliseconds, unblock done channel in 2 goroutines
225242
<-debouncer.Done()
226243

227-
fmt.Println(len(debouncer.Done()))
244+
time.Sleep(200 * time.Millisecond)
228245

229246
if *countPtr != expectedCounter {
230247
t.Errorf("Expected count %d, was %d", expectedCounter, *countPtr)
231248
}
232249
}
250+
251+
func TestDoneHangBeforeSendSignal(t *testing.T) {
252+
debouncer := godebouncer.New(200 * time.Millisecond).WithTriggered(func() {})
253+
select {
254+
case <-debouncer.Done():
255+
t.Error("Done() must hang when being called before SendSignal()")
256+
case <-time.After(time.Second):
257+
}
258+
}
259+
260+
func TestDoneHangIfBeingCalledTwice(t *testing.T) {
261+
debouncer := godebouncer.New(200 * time.Millisecond).WithTriggered(func() {})
262+
debouncer.SendSignal()
263+
<-debouncer.Done()
264+
265+
select {
266+
case <-debouncer.Done():
267+
t.Error("Done() must hang if being called twice")
268+
case <-time.After(time.Second):
269+
}
270+
}

0 commit comments

Comments
 (0)