From c4bfd3574907fcd59d36a63ce21126de52b4520b Mon Sep 17 00:00:00 2001 From: tgrlbyrk Date: Sun, 18 Aug 2024 21:06:22 +0300 Subject: [PATCH] Add missing tests and update README.md --- README.md | 32 ++++++++++++++++++++-- app.go | 2 +- strategy/poll/double_poll_interval.go | 14 +++++++++- strategy/poll/double_poll_interval_test.go | 22 +++++++++++++++ strategy/poll/fixed_poll_interval.go | 14 +++++++++- strategy/poll/fixed_poll_interval_test.go | 22 +++++++++++++++ 6 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 strategy/poll/double_poll_interval_test.go create mode 100644 strategy/poll/fixed_poll_interval_test.go diff --git a/README.md b/README.md index 4e8f1b1..7d2234e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,16 @@ go-await lets you use to synchronize async operations. It is inspired from popular Java library 'awaitility [https://github.com/awaitility/awaitility]' ## Install +With [Go's module support](https://go.dev/wiki/Modules#how-to-use-modules), `go [build|run|test]` automatically fetches the necessary dependencies when you add the import in your code: -```bash -go get github.com/bayraktugrul/go-await +```sh +import "github.com/bayraktugrul/go-await" +``` + +Alternatively, use `go get`: + +```sh +go get -u github.com/bayraktugrul/go-await ``` ## Examples @@ -37,6 +44,27 @@ err := await.New().PollInterval(500 * time.Millisecond).AtMost(2 * time.Second). if err != nil {} ``` +### Await with custom poll interval strategy + +The default polling strategy is Fixed, returning the same interval for each iteration. You can customize this by setting a different poll interval strategy. +```go + +producer.publishMessage(orderCreatedMessage) + +// waits with double poll interval strategy +// for up to 2 seconds until repo.Exist returns true, +// using a polling interval of 500ms +err := await.New(). + PollStrategy(poll.Double). + PollInterval(100 * time.Millisecond). + AtMost(2 * time.Second). + Await(func() bool { + return repo.Exist(id) // any condition you want to wait for until it returns true + }) + +if err != nil {} +``` + ## Credits * [Tuğrul Bayrak](https://github.com/bayraktugrul) diff --git a/app.go b/app.go index 5fa93f5..2e5dc53 100644 --- a/app.go +++ b/app.go @@ -59,7 +59,7 @@ func (a *app) Await(waitFunc func() bool) error { go until(waitFunc, result) - iter := 0 + iter := 1 for { select { case finish := <-result: diff --git a/strategy/poll/double_poll_interval.go b/strategy/poll/double_poll_interval.go index 3c95131..e2901e5 100644 --- a/strategy/poll/double_poll_interval.go +++ b/strategy/poll/double_poll_interval.go @@ -5,7 +5,19 @@ import ( "time" ) -// DoublePollInterval TODO:write explanation +// DoublePollInterval calculates the poll interval for a given iteration +// using an exponential backoff strategy. The interval is doubled with each iteration, +// starting from the initial interval value provided. +// +// Iterations start from 0 (zero). At each step, the interval is multiplied by 2. +// +// Example1: For iteration: 3 and interval: 100 * time.Millisecond +// +// Step 1: 100ms * 2 = 200ms +// Step 2: 200ms * 2 = 400ms +// Step 3: 400ms * 2 = 800ms +// +// Result: 800ms func DoublePollInterval(iteration int, interval time.Duration) time.Duration { return utils.MultiplyDuration(iteration, interval) } diff --git a/strategy/poll/double_poll_interval_test.go b/strategy/poll/double_poll_interval_test.go new file mode 100644 index 0000000..28f3f93 --- /dev/null +++ b/strategy/poll/double_poll_interval_test.go @@ -0,0 +1,22 @@ +package poll_test + +import ( + "github.com/bayraktugrul/go-await/strategy/poll" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func Test_DoubleInterval(t *testing.T) { + t.Run("it should return 800ms ms when iteration is 3 and interval is 100ms", func(t *testing.T) { + //given + iteration := 3 + interval := 100 * time.Millisecond + + //when + result := poll.DoublePollInterval(iteration, interval) + + //then + assert.Equal(t, 800*time.Millisecond, result) + }) +} diff --git a/strategy/poll/fixed_poll_interval.go b/strategy/poll/fixed_poll_interval.go index 5b2b210..3c336fb 100644 --- a/strategy/poll/fixed_poll_interval.go +++ b/strategy/poll/fixed_poll_interval.go @@ -2,7 +2,19 @@ package poll import "time" -// FixedPollInterval poll interval strategy always returns given interval +// FixedPollInterval is a poll interval strategy that consistently returns the same fixed interval, +// regardless of the iteration count. This strategy ensures that the polling frequency remains constant +// throughout all iterations, with no backoff or variation. +// +// Example: For iteration: 0 to N and interval: 100 * time.Millisecond +// +// Iteration 0: 100ms +// Iteration 1: 100ms +// Iteration 2: 100ms +// ... +// Iteration N: 100ms +// +// Result: The interval remains fixed at 100ms for every iteration. func FixedPollInterval(iteration int, interval time.Duration) time.Duration { return interval } diff --git a/strategy/poll/fixed_poll_interval_test.go b/strategy/poll/fixed_poll_interval_test.go new file mode 100644 index 0000000..120d509 --- /dev/null +++ b/strategy/poll/fixed_poll_interval_test.go @@ -0,0 +1,22 @@ +package poll_test + +import ( + "github.com/bayraktugrul/go-await/strategy/poll" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func Test_FixedInterval(t *testing.T) { + t.Run("it should return 100ms ms when iteration is 3 and interval is 100ms", func(t *testing.T) { + //given + iteration := 3 + interval := 100 * time.Millisecond + + //when + result := poll.FixedPollInterval(iteration, interval) + + //then + assert.Equal(t, 100*time.Millisecond, result) + }) +}