Skip to content

Commit

Permalink
add debounc and throttle
Browse files Browse the repository at this point in the history
  • Loading branch information
delaneyj committed Nov 23, 2024
1 parent 49c1d0c commit f5b641f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
version: "3"

vars:
VERSION: 0.3.13
VERSION: 0.3.14

interval: 200ms

Expand Down
91 changes: 91 additions & 0 deletions logic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package toolbelt

import (
"fmt"
"sync"
"time"
)

type ErrFunc func() error

// Throttle will only allow the function to be called once every d duration.
func Throttle(d time.Duration, fn ErrFunc) ErrFunc {
shouldWait := false
mu := &sync.RWMutex{}

checkShoulWait := func() bool {
mu.RLock()
defer mu.RUnlock()
return shouldWait
}

return func() error {
if checkShoulWait() {
return nil
}

mu.Lock()
defer mu.Unlock()
shouldWait = true

go func() {
<-time.After(d)
shouldWait = false
}()

if err := fn(); err != nil {
return fmt.Errorf("throttled function failed: %w", err)
}

return nil
}
}

// Debounce will only call the function after d duration has passed since the last call.
func Debounce(d time.Duration, fn ErrFunc) ErrFunc {
var t *time.Timer
mu := &sync.RWMutex{}

return func() error {
mu.Lock()
defer mu.Unlock()

if t != nil && !t.Stop() {
<-t.C
}

t = time.AfterFunc(d, func() {
if err := fn(); err != nil {
fmt.Printf("debounced function failed: %v\n", err)
}
})

return nil
}
}

func CallNTimesWithDelay(d time.Duration, n int, fn ErrFunc) ErrFunc {
return func() error {
called := 0
for {
shouldCall := false
if n < 0 {
shouldCall = true
} else if called < n {
shouldCall = true
}
if !shouldCall {
break
}

if err := fn(); err != nil {
return fmt.Errorf("call n times with delay failed: %w", err)
}
called++

<-time.After(d)
}

return nil
}
}

0 comments on commit f5b641f

Please sign in to comment.