Skip to content

Commit f272b90

Browse files
authored
feat: Add ability to disable retries (#67)
1 parent 7d342e7 commit f272b90

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

lib/ld-eventsource/client.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ class Client
8989
# an Array, it will be converted to JSON and sent as the request body. A string will be sent as a non-JSON
9090
# request body. If payload responds to #call, it will be invoked on each
9191
# request to generate the payload dynamically.
92+
# @param retry_enabled [Boolean] (true) whether to retry connections after failures. If false, the client
93+
# will exit after the first connection failure instead of attempting to reconnect.
9294
# @yieldparam [Client] client the new client instance, before opening the connection
9395
#
9496
def initialize(uri,
@@ -102,9 +104,11 @@ def initialize(uri,
102104
logger: nil,
103105
socket_factory: nil,
104106
method: "GET",
105-
payload: nil)
107+
payload: nil,
108+
retry_enabled: true)
106109
@uri = URI(uri)
107110
@stopped = Concurrent::AtomicBoolean.new(false)
111+
@retry_enabled = retry_enabled
108112

109113
@headers = headers.clone
110114
@connect_timeout = connect_timeout
@@ -256,6 +260,8 @@ def run_stream
256260
rescue StandardError => e
257261
log_and_dispatch_error(e, "Unexpected error while closing stream")
258262
end
263+
264+
return close unless @retry_enabled
259265
end
260266
end
261267

spec/client_spec.rb

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,4 +737,90 @@ def test_object.to_s
737737
end
738738
end
739739
end
740+
741+
describe "retry parameter" do
742+
it "defaults to true (retries enabled)" do
743+
events_body = simple_event_1_text
744+
with_server do |server|
745+
attempt = 0
746+
server.setup_response("/") do |req,res|
747+
attempt += 1
748+
if attempt == 1
749+
res.status = 500
750+
res.body = "server error"
751+
res.keep_alive = false
752+
else
753+
send_stream_content(res, events_body, keep_open: true)
754+
end
755+
end
756+
757+
event_sink = Queue.new
758+
error_sink = Queue.new
759+
client = subject.new(server.base_uri, reconnect_time: reconnect_asap) do |c|
760+
c.on_event { |event| event_sink << event }
761+
c.on_error { |error| error_sink << error }
762+
end
763+
764+
with_client(client) do |c|
765+
expect(event_sink.pop).to eq(simple_event_1)
766+
expect(error_sink.pop).to eq(SSE::Errors::HTTPStatusError.new(500, "server error"))
767+
expect(attempt).to eq 2 # Should have retried
768+
end
769+
end
770+
end
771+
772+
it "allows retries when retry_enabled: true" do
773+
events_body = simple_event_1_text
774+
with_server do |server|
775+
attempt = 0
776+
server.setup_response("/") do |req,res|
777+
attempt += 1
778+
if attempt == 1
779+
res.status = 500
780+
res.body = "server error"
781+
res.keep_alive = false
782+
else
783+
send_stream_content(res, events_body, keep_open: true)
784+
end
785+
end
786+
787+
event_sink = Queue.new
788+
error_sink = Queue.new
789+
client = subject.new(server.base_uri, reconnect_time: reconnect_asap, retry_enabled: true) do |c|
790+
c.on_event { |event| event_sink << event }
791+
c.on_error { |error| error_sink << error }
792+
end
793+
794+
with_client(client) do |c|
795+
expect(event_sink.pop).to eq(simple_event_1)
796+
expect(error_sink.pop).to eq(SSE::Errors::HTTPStatusError.new(500, "server error"))
797+
expect(attempt).to eq 2 # Should have retried
798+
end
799+
end
800+
end
801+
802+
it "disables retries when retry_enabled: false" do
803+
with_server do |server|
804+
attempt = 0
805+
server.setup_response("/") do |req,res|
806+
attempt += 1
807+
res.status = 500
808+
res.body = "server error"
809+
res.keep_alive = false
810+
end
811+
812+
error_sink = Queue.new
813+
client = subject.new(server.base_uri, retry_enabled: false) do |c|
814+
c.on_error { |error| error_sink << error }
815+
end
816+
817+
# Give the client some time to attempt connection and fail
818+
sleep(0.5)
819+
client.close
820+
821+
expect(error_sink.pop).to eq(SSE::Errors::HTTPStatusError.new(500, "server error"))
822+
expect(attempt).to eq 1 # Should not have retried
823+
end
824+
end
825+
end
740826
end

0 commit comments

Comments
 (0)