diff --git a/README.md b/README.md index c6e4b04..c32ebbd 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Octopoller exposes a single function `poll`. Here is what the API looks like: # # wait - The time delay in seconds between polls (default is 1 second) # - When given the argument `:exponentially` the action will be retried with exponetial backoff +# - When given 0, false or nil, the action will be retried without wait # timeout - The maximum number of seconds the poller will execute # retries - The maximum number of times the action will be retried # yield - A block that will execute, and if `:re_poll` is returned it will re-run diff --git a/lib/octopoller.rb b/lib/octopoller.rb index aa6a431..0d4de1d 100644 --- a/lib/octopoller.rb +++ b/lib/octopoller.rb @@ -16,6 +16,8 @@ class TooManyAttemptsError < StandardError; end # raise - Raises an Octopoller::TimeoutError if the timeout is reached # raise - Raises an Octopoller::TooManyAttemptsError if the retries is reached def poll(wait: 1, timeout: nil, retries: nil) + wait = 0 if [nil, false].include?(wait) + Octopoller.validate_arguments(wait, timeout, retries) exponential_backoff = (wait == :exponentially) @@ -45,7 +47,7 @@ def self.validate_arguments(wait, timeout, retries) raise ArgumentError, "Must pass an argument to either `timeout` or `retries`" end exponential_backoff = wait == :exponentially - raise ArgumentError, "Cannot wait backwards in time" unless exponential_backoff || wait.positive? + raise ArgumentError, "Cannot wait backwards in time" if !exponential_backoff && wait.negative? raise ArgumentError, "Timed out without even being able to try" if timeout&.negative? raise ArgumentError, "Cannot retry something a negative number of times" if retries&.negative? end diff --git a/spec/octopoller_spec.rb b/spec/octopoller_spec.rb index 77146f5..f027e18 100644 --- a/spec/octopoller_spec.rb +++ b/spec/octopoller_spec.rb @@ -14,6 +14,23 @@ .to raise_error(ArgumentError, "Timed out without even being able to try") end + it "polls without wait" do + [0, false, nil].each do |wait| + tries, start, duration = 0, Time.now, nil + result = Octopoller.poll(wait: wait, timeout: 0.05) do + tries += 1 + if tries == 3 + duration = Time.now - start + "Success!" + else + :re_poll + end + end + expect(result).to eq("Success!") + expect(duration).to be < 0.1 + end + end + it "polls until timeout" do expect do Octopoller.poll(wait: 0.01, timeout: 0.05) do @@ -66,7 +83,7 @@ it "poll until max retries reached" do expect do - Octopoller.poll(wait: 0.01, retries: 2) do + Octopoller.poll(wait: false, retries: 2) do :re_poll end end.to raise_error(Octopoller::TooManyAttemptsError, "Polled maximum number of attempts") @@ -75,7 +92,7 @@ it "tries exactly the number of retries" do attempts = 0 expect do - Octopoller.poll(wait: 0.01, retries: 3) do + Octopoller.poll(wait: false, retries: 3) do attempts += 1 :re_poll end @@ -107,7 +124,7 @@ it "try until successful return" do tried = false - result = Octopoller.poll(wait: 0.01, retries: 1) do + result = Octopoller.poll(wait: false, retries: 1) do if tried "Success!" else @@ -120,7 +137,7 @@ it "doesn't swallow a raised error" do expect do - Octopoller.poll(wait: 0.01, retries: 0) do + Octopoller.poll(wait: false, retries: 0) do raise StandardError, "An error occured" end end.to raise_error(StandardError, "An error occured")