@@ -84,6 +84,8 @@ defmodule Crux.Gateway.Connection.Gun do
84
84
@ connecting :connecting
85
85
@ connected :connected
86
86
87
+ @ attempt_limit 5
88
+
87
89
defstruct [
88
90
:parent ,
89
91
:host ,
@@ -93,6 +95,7 @@ defmodule Crux.Gateway.Connection.Gun do
93
95
:zlib ,
94
96
:buffer ,
95
97
:conn ,
98
+ :attempts ,
96
99
:expect_disconnect
97
100
]
98
101
@@ -109,6 +112,8 @@ defmodule Crux.Gateway.Connection.Gun do
109
112
buffer: binary ( ) ,
110
113
# WS connection wrapper process
111
114
conn: pid ( ) | nil ,
115
+ # Limit the amount of attempts to establish a connection
116
+ attempts: non_neg_integer ( ) ,
112
117
# Whether we are expecting a gun_down / disconnect
113
118
# and do not want to notify the spawning process again
114
119
expect_disconnect: boolean ( )
@@ -136,6 +141,7 @@ defmodule Crux.Gateway.Connection.Gun do
136
141
zlib: nil ,
137
142
buffer: << >> ,
138
143
conn: nil ,
144
+ attempts: 0 ,
139
145
expect_disconnect: false
140
146
}
141
147
@@ -184,30 +190,54 @@ defmodule Crux.Gateway.Connection.Gun do
184
190
z = Zlib . open ( )
185
191
Zlib . inflateInit ( z )
186
192
187
- Logger . debug ( fn -> "Starting a process to connect to #{ data . host } :#{ data . port } " end )
193
+ attempts = data . attempts + 1
194
+ data = % { data | attempts: attempts }
195
+
196
+ Logger . debug ( fn ->
197
+ "Starting a process to connect to #{ data . host } :#{ data . port } (Attempt: #{ attempts } / #{ @ attempt_limit } )"
198
+ end )
188
199
189
200
# > Gun does not currently support Websocket over HTTP/2.
190
201
{ :ok , conn } = Gun . open ( data . host , data . port , % { protocols: [ :http ] } )
191
202
192
203
Logger . debug ( fn -> "Process started, waiting for its connection to be up." end )
193
204
194
- { :ok , :http } = Gun . await_up ( conn )
205
+ conn
206
+ |> Gun . await_up ( )
207
+ |> case do
208
+ { :ok , :http } ->
209
+ Logger . debug ( fn ->
210
+ "Connection is up, now upgrading it to use the WebSocket protocol, using " <>
211
+ data . path <> data . query
212
+ end )
195
213
196
- Logger . debug ( fn ->
197
- "Connection is up, now upgrading it to use the WebSocket protocol, using " <>
198
- data . path <> data . query
199
- end )
214
+ stream_ref = Gun . ws_upgrade ( conn , data . path <> data . query )
215
+ :ok = await_upgrade ( conn , stream_ref )
216
+
217
+ Logger . debug ( fn ->
218
+ "Connection upgraded to use the WebSocket protocol, we are good to go!"
219
+ end )
220
+
221
+ send_connected ( data )
200
222
201
- stream_ref = Gun . ws_upgrade ( conn , data . path <> data . query )
202
- :ok = await_upgrade ( conn , stream_ref )
223
+ data = % { data | conn: conn , zlib: z , attempts: 0 }
203
224
204
- Logger . debug ( fn -> "Connection upgraded to use the WebSocket protocol, we are good to go!" end )
225
+ { :keep_state , data , { :timeout , 0 , :connected } }
205
226
206
- send_connected ( data )
227
+ { :error , :timeout } when attempts >= @ attempt_limit ->
228
+ Logger . error ( fn ->
229
+ "Connection timed out, no attempts remaining, won't retry. (#{ attempts } / #{ @ attempt_limit } )"
230
+ end )
207
231
208
- data = % { data | conn: conn , zlib: z }
232
+ { :stop , :connection_failure , data }
209
233
210
- { :keep_state , data , { :timeout , 0 , :connected } }
234
+ { :error , :timeout } ->
235
+ Logger . warn ( fn ->
236
+ "Connection timed out, will retry. (#{ attempts } / #{ @ attempt_limit } )"
237
+ end )
238
+
239
+ { :repeat_state , data }
240
+ end
211
241
end
212
242
213
243
def connecting ( :timeout , :connected , data ) do
0 commit comments