@@ -31,6 +31,14 @@ export class WebSocketClassProvider {
3131 }
3232}
3333
34+ /**
35+ * Object used to pass partial websocket transport state into url config function.
36+ */
37+ export interface WebSocketUrlConfigFunctionParameters {
38+ /** Number of times streamHandler was called without a responsive connection */
39+ streamHandlerInvocationsWithNoConnection : number
40+ }
41+
3442/**
3543 * Config object that is provided to the WebSocketTransport constructor.
3644 */
@@ -39,6 +47,7 @@ export interface WebSocketTransportConfig<T extends WebsocketTransportGenerics>
3947 url : (
4048 context : EndpointContext < T > ,
4149 desiredSubs : TypeFromDefinition < T [ 'Parameters' ] > [ ] ,
50+ urlConfigFunctionParameters : WebSocketUrlConfigFunctionParameters ,
4251 ) => Promise < string > | string
4352
4453 /** Optional parameters used when establishing the WebSocket connection */
@@ -149,6 +158,7 @@ export class WebSocketTransport<
149158 currentUrl = ''
150159 lastMessageReceivedAt = 0
151160 connectionOpenedAt = 0
161+ streamHandlerInvocationsWithNoConnection = 0
152162
153163 constructor ( private config : WebSocketTransportConfig < T > ) {
154164 super ( )
@@ -328,11 +338,6 @@ export class WebSocketTransport<
328338 return
329339 }
330340
331- // We want to check if the URL we calculate is different from the one currently connected.
332- // This is because some providers handle subscriptions on the URLs and not through messages.
333- const urlFromConfig = await this . config . url ( context , subscriptions . desired )
334- const urlChanged = this . currentUrl !== urlFromConfig
335-
336341 // We want to check that if we have a connection, it hasn't gone stale. That is,
337342 // since opening it, have we had any activity from the provider.
338343 const now = Date . now ( )
@@ -351,7 +356,27 @@ export class WebSocketTransport<
351356 timeSinceLastActivity: ${ timeSinceLastActivity } |
352357 subscriptionUnresponsiveTtl: ${ context . adapterSettings . WS_SUBSCRIPTION_UNRESPONSIVE_TTL } |
353358 connectionUnresponsive: ${ connectionUnresponsive } |
354- ` )
359+ ` )
360+
361+ // The var connectionUnresponsive checks whether the time since last activity on
362+ // _any_ successful open connection (or 0 if we haven't had one yet) has exceeded
363+ // WS_SUBSCRIPTION_UNRESPONSIVE_TTL. There is interplay with WS_SUBSCRIPTION_TTL
364+ // to determine minimum TTL of an open connection given no explicit connection errors.
365+ if ( connectionUnresponsive ) {
366+ this . streamHandlerInvocationsWithNoConnection += 1
367+ logger . trace (
368+ `The connection is unresponsive, incremented streamHandlerIterationsWithNoConnection = ${ this . streamHandlerInvocationsWithNoConnection } ` ,
369+ )
370+ }
371+
372+ // We want to check if the URL we calculate is different from the one currently connected.
373+ // This is because some providers handle subscriptions on the URLs and not through messages.
374+ // Subclasses may also implement alternate URL handling logic,
375+ // eg: toggling through multiple possible URLs in case of failure.
376+ const urlFromConfig = await this . config . url ( context , subscriptions . desired , {
377+ streamHandlerInvocationsWithNoConnection : this . streamHandlerInvocationsWithNoConnection ,
378+ } )
379+ const urlChanged = this . currentUrl !== urlFromConfig
355380
356381 // Check if we should close the current connection
357382 if ( ! connectionClosed && ( urlChanged || connectionUnresponsive ) ) {
0 commit comments