From 41328913261e771d20409cccbf7f0f9aca4127bb Mon Sep 17 00:00:00 2001 From: Vitaly Isaev Date: Mon, 6 Sep 2021 13:57:10 +0300 Subject: [PATCH 1/2] CFS-2079 | feat: fire predicate one time immediately, start polling after --- asyncwait.go | 21 ++++++++++++++++++--- go.mod | 3 +++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 go.mod diff --git a/asyncwait.go b/asyncwait.go index 6101c39..67127cc 100644 --- a/asyncwait.go +++ b/asyncwait.go @@ -28,18 +28,33 @@ func NewAsyncWait(timeout, pollInterval time.Duration) AsyncWait { } } -// Wait while timeout, make polls every pollInterval for the predicate while is not truth +// Wait while timeout, make polls every pollInterval for the predicate until it returns true func (aw asyncWait) Wait(predicate func() bool) bool { ctx, cancel := context.WithTimeout(context.Background(), aw.timeout) defer cancel() + ticker := time.NewTicker(aw.pollInterval) + defer ticker.Stop() + + runPredicate := func() { + if predicate() { + select { + case aw.doneCh <- struct{}{}: + case <-ctx.Done(): + } + } + } + + // Try to execute predicate immediately + go runPredicate() + + // If the first call was not successful, start polling for { select { case <-aw.doneCh: return true case <-ctx.Done(): - return false - case <-time.After(aw.pollInterval): + case <-ticker.C: go func() { if predicate() { select { diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4908ed9 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/vitalyisaev2/asyncwait + +go 1.16 From b3a13d64583568c6f046d1c3450531fff0323ef0 Mon Sep 17 00:00:00 2001 From: Vitaly Isaev Date: Mon, 6 Sep 2021 14:27:15 +0300 Subject: [PATCH 2/2] CFS-2079 | fix: return false if context is done --- asyncwait.go | 1 + 1 file changed, 1 insertion(+) diff --git a/asyncwait.go b/asyncwait.go index 67127cc..f303c8f 100644 --- a/asyncwait.go +++ b/asyncwait.go @@ -54,6 +54,7 @@ func (aw asyncWait) Wait(predicate func() bool) bool { case <-aw.doneCh: return true case <-ctx.Done(): + return false case <-ticker.C: go func() { if predicate() {