Skip to content

Commit

Permalink
adds call limit before triggering
Browse files Browse the repository at this point in the history
  • Loading branch information
jonfriesen committed Feb 16, 2024
1 parent 9caf5cf commit 1b04201
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 33 deletions.
2 changes: 0 additions & 2 deletions .github/FUNDING.yml

This file was deleted.

13 changes: 3 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
on:
push:
branches: [ master ]
branches: [ main ]
pull_request:
workflow_dispatch:
name: Test
Expand All @@ -10,8 +10,8 @@ jobs:
test:
strategy:
matrix:
go-version: [1.18.x]
os: [ubuntu-latest, windows-latest]
go-version: [1.22.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
Expand Down Expand Up @@ -41,10 +41,3 @@ jobs:
run: golint ./...
- name: Test
run: go test -race .
- name: Upload coverage
if: success() && matrix.os == 'ubuntu-latest'
run: |
curl -s https://codecov.io/bash | bash
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
shell: bash
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
# Go Debounce

[![Tests on Linux, MacOS and Windows](https://github.com/bep/debounce/workflows/Test/badge.svg)](https://github.com/bep/debounce/actions?query=workflow:Test)
[![GoDoc](https://godoc.org/github.com/bep/debounce?status.svg)](https://godoc.org/github.com/bep/debounce)
[![Go Report Card](https://goreportcard.com/badge/github.com/bep/debounce)](https://goreportcard.com/report/github.com/bep/debounce)
[![codecov](https://codecov.io/gh/bep/debounce/branch/master/graph/badge.svg)](https://codecov.io/gh/bep/debounce)
[![Release](https://img.shields.io/github/release/bep/debounce.svg?style=flat-square)](https://github.com/bep/debounce/releases/latest)
[![Tests on Linux, MacOS and Windows](https://github.com/qpoint-io/debounce/workflows/Test/badge.svg)](https://github.com/qpoint-io/debounce/actions?query=workflow:Test)
[![GoDoc](https://godoc.org/github.com/qpoint-io/debounce?status.svg)](https://godoc.org/github.com/qpoint-io/debounce)

## Example

Expand All @@ -16,7 +13,7 @@ func ExampleNew() {
atomic.AddUint64(&counter, 1)
}

debounced := debounce.New(100 * time.Millisecond)
debounced := debounce.New(100 * time.Millisecond, 50)

for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
Expand Down
48 changes: 40 additions & 8 deletions debounce.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,63 @@ import (
"time"
)

// New returns a debounced function that takes another functions as its argument.
// New returns a debounced function that takes another function as its argument.
// This function will be called when the debounced function stops being called
// for the given duration.
// for the given duration, provided the maximum count hasn't been exceeded.
// Once the maximum count is exceeded, the function is executed one last time
// and the debouncer is reset.
// The debounced function can be invoked with different functions, if needed,
// the last one will win.
func New(after time.Duration) func(f func()) {
d := &debouncer{after: after}
func New(after time.Duration, countLimit uint64) func(f func()) {
d := &debouncer{
after: after,
countLimit: countLimit,
}

return func(f func()) {
d.add(f)
}
}

type debouncer struct {
mu sync.Mutex
after time.Duration
timer *time.Timer
mu sync.Mutex
after time.Duration
timer *time.Timer
count uint64
countLimit uint64
}

func (d *debouncer) add(f func()) {
d.mu.Lock()
defer d.mu.Unlock()

// Increment the count
d.count++

// If count exceeds maxCount, execute the function and reset
if d.count > d.countLimit {
if d.timer != nil {
d.timer.Stop()
d.timer = nil
}

f()

// Reset the count for the next iteration
d.count = 0
return
}

if d.timer != nil {
d.timer.Stop()
}
d.timer = time.AfterFunc(d.after, f)
d.timer = time.AfterFunc(d.after, func() {
d.mu.Lock()
defer d.mu.Unlock()

f()

// Reset the count after the function is executed
d.count = 0
})
}
34 changes: 28 additions & 6 deletions debounce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"
"time"

"github.com/bep/debounce"
"github.com/qpoint-io/debounce"
)

func TestDebounce(t *testing.T) {
Expand All @@ -28,7 +28,7 @@ func TestDebounce(t *testing.T) {
atomic.AddUint64(&counter2, 2)
}

debounced := debounce.New(100 * time.Millisecond)
debounced := debounce.New(100*time.Millisecond, 1000)

for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
Expand Down Expand Up @@ -64,7 +64,7 @@ func TestDebounceConcurrentAdd(t *testing.T) {

var flag uint64

debounced := debounce.New(100 * time.Millisecond)
debounced := debounce.New(100*time.Millisecond, 1000)

for i := 0; i < 10; i++ {
wg.Add(1)
Expand Down Expand Up @@ -95,7 +95,7 @@ func TestDebounceDelayed(t *testing.T) {
atomic.AddUint64(&counter1, 1)
}

debounced := debounce.New(100 * time.Millisecond)
debounced := debounce.New(100*time.Millisecond, 1000)

time.Sleep(110 * time.Millisecond)

Expand All @@ -117,7 +117,7 @@ func BenchmarkDebounce(b *testing.B) {
atomic.AddUint64(&counter, 1)
}

debounced := debounce.New(100 * time.Millisecond)
debounced := debounce.New(100*time.Millisecond, 1000)

b.ResetTimer()
for i := 0; i < b.N; i++ {
Expand All @@ -137,7 +137,7 @@ func ExampleNew() {
atomic.AddUint64(&counter, 1)
}

debounced := debounce.New(100 * time.Millisecond)
debounced := debounce.New(100*time.Millisecond, 1000)

for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
Expand All @@ -152,3 +152,25 @@ func ExampleNew() {
fmt.Println("Counter is", c)
// Output: Counter is 3
}

func TestDebouncerCountLimit(t *testing.T) {
after := 1 * time.Hour
countLimit := uint64(3)

var execCount uint64

f := func() {
atomic.AddUint64(&execCount, 1)
}

debounced := debounce.New(after, countLimit)

for i := uint64(0); i < countLimit+1; i++ {
debounced(f)
}

expectedExecCount := uint64(1)
if atomic.LoadUint64(&execCount) != expectedExecCount {
t.Errorf("Expected function to be executed %d time(s), but got %d", expectedExecCount, atomic.LoadUint64(&execCount))
}
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module github.com/bep/debounce
module github.com/qpoint-io/debounce

go 1.22.0

0 comments on commit 1b04201

Please sign in to comment.