@@ -10,7 +10,7 @@ module SSE
1010 module EventSource
1111 class Client
1212 DEFAULT_READ_TIMEOUT = 70
13- CONNECT_TIMEOUT = 30_000
13+ CONNECT_TIMEOUT = 30
1414 OK_CODE = 200
1515 KEEP_ALIVE_RESPONSE = "c\r \n :keepalive\n \n \r \n " . freeze
1616 ERROR_EVENT_TYPE = 'error' . freeze
@@ -37,17 +37,15 @@ def initialize(config,
3737 end
3838
3939 def close ( status = nil )
40- unless connected?
41- @config . logger . debug ( 'SSEClient already disconected.' ) if @config . debug_enabled
42- return
43- end
44- @config . logger . debug ( "Closing SSEClient socket" ) if @config . debug_enabled
40+ return if @socket . nil?
4541
42+ @config . logger . debug ( "Closing SSEClient socket" ) if @config . debug_enabled
4643 push_status ( status )
4744 @connected . make_false
4845 @socket . sync_close = true if @socket . is_a? OpenSSL ::SSL ::SSLSocket
4946 @socket . close
50- @config . logger . debug ( "SSEClient socket state #{ @socket . state } " ) if @socket . is_a? OpenSSL ::SSL ::SSLSocket && @config . debug_enabled
47+ @config . logger . debug ( "SSEClient socket state #{ @socket . state } " ) if @socket . is_a? ( OpenSSL ::SSL ::SSLSocket ) && @config . debug_enabled
48+ @socket = nil
5149 rescue StandardError => e
5250 @config . logger . error ( "SSEClient close Error: #{ e . inspect } " )
5351 end
@@ -80,21 +78,21 @@ def connect_thread(latch)
8078 @config . threads [ :connect_stream ] = Thread . new do
8179 @config . logger . info ( 'Starting connect_stream thread ...' )
8280 new_status = connect_stream ( latch )
83- push_status ( new_status )
81+ push_status ( new_status ) unless new_status . nil?
8482 @config . logger . info ( 'connect_stream thread finished.' )
8583 end
8684 end
8785
8886 def connect_stream ( latch )
89- return Constants ::PUSH_NONRETRYABLE_ERROR unless socket_write ( latch )
87+ return Constants ::PUSH_RETRYABLE_ERROR unless socket_write ( latch )
9088 while connected? || @first_event . value
9189 begin
9290 if IO . select ( [ @socket ] , nil , nil , @read_timeout )
9391 begin
9492 partial_data = @socket . readpartial ( 10_000 )
95- read_first_event ( partial_data , latch )
9693
97- raise 'eof exception' if partial_data == :eof
94+ first_event_status = read_first_event ( partial_data , latch )
95+ return first_event_status unless first_event_status . nil?
9896 rescue IO ::WaitReadable => e
9997 @config . logger . debug ( "SSE client IO::WaitReadable transient error: #{ e . inspect } " ) if @config . debug_enabled
10098 IO . select ( [ @socket ] , nil , nil , @read_timeout )
@@ -107,8 +105,8 @@ def connect_stream(latch)
107105 @config . logger . error ( "SSE read operation timed out!: #{ e . inspect } " )
108106 return Constants ::PUSH_RETRYABLE_ERROR
109107 rescue EOFError => e
110- @config . logger . error ( "SSE read operation EOF Exception! : #{ e . inspect } " )
111- raise 'eof exception'
108+ @config . logger . error ( "SSE read operation EOF, server closed the connection, will reconnect : #{ e . inspect } " )
109+ return Constants :: PUSH_RETRYABLE_ERROR
112110 rescue Errno ::EBADF , IOError => e
113111 @config . logger . error ( "SSE read operation EBADF or IOError: #{ e . inspect } " )
114112 return Constants ::PUSH_RETRYABLE_ERROR
@@ -123,14 +121,9 @@ def connect_stream(latch)
123121 @config . logger . error ( "SSE read operation timed out, no data available." )
124122 return Constants ::PUSH_RETRYABLE_ERROR
125123 end
126- rescue Errno ::EBADF
127- @config . logger . debug ( "SSE socket is not connected (Errno::EBADF)" ) if @config . debug_enabled
128- break
129- rescue RuntimeError
130- raise 'eof exception'
131124 rescue Exception => e
132125 @config . logger . debug ( "SSE socket is not connected: #{ e . inspect } " ) if @config . debug_enabled
133- break
126+ return Constants :: PUSH_RETRYABLE_ERROR
134127 end
135128
136129 process_data ( partial_data )
@@ -157,19 +150,20 @@ def read_first_event(data, latch)
157150 response_code = @event_parser . first_event ( data )
158151 @config . logger . debug ( "SSE client first event code: #{ response_code } " ) if @config . debug_enabled
159152
160- error_event = false
161- events = @event_parser . parse ( data )
162- events . each { |e | error_event = true if e . event_type == ERROR_EVENT_TYPE }
163153 @first_event . make_false
164154
165- if response_code == OK_CODE && !error_event
166- @connected . make_true
167- @config . logger . debug ( "SSE client first event Connected is true" ) if @config . debug_enabled
168- @telemetry_runtime_producer . record_streaming_event ( Telemetry ::Domain ::Constants ::SSE_CONNECTION_ESTABLISHED , nil )
169- push_status ( Constants ::PUSH_CONNECTED )
155+ if response_code != OK_CODE
156+ @config . logger . error ( "SSE first event failed, code: #{ response_code } " )
157+ latch . count_down
158+ return Constants ::PUSH_RETRYABLE_ERROR
170159 end
171160
161+ @connected . make_true
162+ @config . logger . debug ( "SSE client first event Connected is true" ) if @config . debug_enabled
163+ @telemetry_runtime_producer . record_streaming_event ( Telemetry ::Domain ::Constants ::SSE_CONNECTION_ESTABLISHED , nil )
164+ push_status ( Constants ::PUSH_CONNECTED )
172165 latch . count_down
166+ return nil
173167 end
174168
175169 def socket_connect
0 commit comments