Skip to content

Commit 66a1be0

Browse files
authored
Allow changing the websocket url in interceptors (#6072)
* Allow changing the websocket url in interceptors * fix KDoc
1 parent 844f794 commit 66a1be0

File tree

12 files changed

+426
-321
lines changed

12 files changed

+426
-321
lines changed

libraries/apollo-api/src/commonMain/kotlin/com/apollographql/apollo/api/http/DefaultHttpRequestComposer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class DefaultHttpRequestComposer(
196196
val variables = buildJsonString {
197197
val uploadAwareWriter = FileUploadAwareJsonWriter(this)
198198
uploadAwareWriter.writeObject {
199-
operation.serializeVariables(this, customScalarAdapters, false)
199+
operation.serializeVariables(writer = this, customScalarAdapters = customScalarAdapters, withDefaultValues = false)
200200
}
201201
check(uploadAwareWriter.collectedUploads().isEmpty()) {
202202
"FileUpload and Http GET are not supported at the same time"

libraries/apollo-runtime/src/commonMain/kotlin/com/apollographql/apollo/network/websocket/WebSocketEngine.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ interface WebSocket {
7979
fun send(text: String)
8080

8181
/**
82-
* Closes the websocket gracefully and asynchronously.
82+
* If the websocket is connected, attempts to close the websocket gracefully and asynchronously by sending
83+
* a close frame with [code] and [reason].
84+
* In all cases, release its resources.
8385
*
8486
* After this call, no more calls to the listener are made
8587
*

libraries/apollo-runtime/src/commonMain/kotlin/com/apollographql/apollo/network/websocket/WebSocketNetworkTransport.kt

Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.apollographql.apollo.network.websocket
22

3-
import com.apollographql.apollo.annotations.ApolloDeprecatedSince
43
import com.apollographql.apollo.annotations.ApolloExperimental
54
import com.apollographql.apollo.api.ApolloRequest
65
import com.apollographql.apollo.api.ApolloResponse
76
import com.apollographql.apollo.api.CustomScalarAdapters
87
import com.apollographql.apollo.api.Operation
9-
import com.apollographql.apollo.api.http.HttpHeader
108
import com.apollographql.apollo.api.json.ApolloJsonElement
119
import com.apollographql.apollo.api.json.jsonReader
1210
import com.apollographql.apollo.api.toApolloResponse
@@ -16,14 +14,16 @@ import com.apollographql.apollo.exception.SubscriptionOperationException
1614
import com.apollographql.apollo.internal.DeferredJsonMerger
1715
import com.apollographql.apollo.network.NetworkTransport
1816
import com.apollographql.apollo.network.websocket.internal.OperationListener
19-
import com.apollographql.apollo.network.websocket.internal.WebSocketHolder
17+
import com.apollographql.apollo.network.websocket.internal.WebSocketPool
2018
import com.benasher44.uuid.uuid4
2119
import kotlinx.coroutines.channels.Channel
2220
import kotlinx.coroutines.channels.ProducerScope
2321
import kotlinx.coroutines.channels.awaitClose
2422
import kotlinx.coroutines.flow.Flow
2523
import kotlinx.coroutines.flow.buffer
2624
import kotlinx.coroutines.flow.callbackFlow
25+
import kotlin.time.Duration
26+
import kotlin.time.Duration.Companion.seconds
2727

2828
/**
2929
* A [NetworkTransport] that uses WebSockets to execute GraphQL operations. Most of the time, it is used
@@ -36,22 +36,20 @@ import kotlinx.coroutines.flow.callbackFlow
3636
class WebSocketNetworkTransport private constructor(
3737
private val webSocketEngine: WebSocketEngine,
3838
private val serverUrl: String,
39-
private val httpHeaders: List<HttpHeader>,
4039
private val wsProtocol: WsProtocol,
41-
private val connectionAcknowledgeTimeoutMillis: Long,
42-
private val pingIntervalMillis: Long,
43-
private val idleTimeoutMillis: Long,
40+
private val connectionAcknowledgeTimeout: Duration,
41+
private val pingInterval: Duration?,
42+
private val idleTimeout: Duration,
4443
private val parserFactory: SubscriptionParserFactory
4544
) : NetworkTransport {
4645

47-
private val holder = WebSocketHolder(
46+
private val pool = WebSocketPool(
4847
webSocketEngine = webSocketEngine,
4948
serverUrl = serverUrl,
50-
httpHeaders = httpHeaders,
5149
wsProtocol = wsProtocol,
52-
connectionAcknowledgeTimeoutMillis = connectionAcknowledgeTimeoutMillis,
53-
pingIntervalMillis = pingIntervalMillis,
54-
idleTimeoutMillis = idleTimeoutMillis
50+
connectionAcknowledgeTimeout = connectionAcknowledgeTimeout,
51+
pingInterval = pingInterval,
52+
idleTimeout = idleTimeout
5553
)
5654

5755
/**
@@ -78,7 +76,8 @@ class WebSocketNetworkTransport private constructor(
7876

7977
val operationListener = DefaultOperationListener(newRequest, this, parserFactory.createParser(request))
8078

81-
val webSocket = holder.acquire()
79+
val webSocket = pool.acquire(newRequest.httpHeaders.orEmpty())
80+
8281
webSocket.startOperation(newRequest, operationListener)
8382

8483
awaitClose {
@@ -91,7 +90,7 @@ class WebSocketNetworkTransport private constructor(
9190
}
9291

9392
override fun dispose() {
94-
holder.close()
93+
pool.close()
9594
}
9695

9796
/**
@@ -102,18 +101,17 @@ class WebSocketNetworkTransport private constructor(
102101
* The given [reason] will be propagated to active subscriptions.
103102
*/
104103
fun closeConnection(reason: ApolloException) {
105-
holder.closeCurrentConnection(reason)
104+
pool.closeAllConnections(reason)
106105
}
107106

108107
@ApolloExperimental
109108
class Builder {
110109
private var serverUrl: String? = null
111-
private var httpHeaders: List<HttpHeader>? = null
112110
private var webSocketEngine: WebSocketEngine? = null
113111
private var wsProtocol: WsProtocol? = null
114-
private var connectionAcknowledgeTimeoutMillis: Long? = null
115-
private var pingIntervalMillis: Long? = null
116-
private var idleTimeoutMillis: Long? = null
112+
private var connectionAcknowledgeTimeout: Duration? = null
113+
private var pingInterval: Duration? = null
114+
private var idleTimeout: Duration? = null
117115
private var parserFactory: SubscriptionParserFactory? = null
118116

119117
/**
@@ -129,29 +127,6 @@ class WebSocketNetworkTransport private constructor(
129127
this.serverUrl = serverUrl
130128
}
131129

132-
/**
133-
* Headers to add to the HTTP handshake query.
134-
*/
135-
fun httpHeaders(headers: List<HttpHeader>) = apply {
136-
this.httpHeaders = headers
137-
}
138-
139-
/**
140-
* Add a [HttpHeader] to the handshake query.
141-
*/
142-
fun addHttpHeader(name: String, value: String) = apply {
143-
this.httpHeaders = this.httpHeaders.orEmpty() + HttpHeader(name, value)
144-
}
145-
146-
/**
147-
* Add a [HttpHeader] to the handshake query.
148-
*/
149-
@Deprecated("use addHttpHeader instead", ReplaceWith("addHttpHeader(name, value)"))
150-
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
151-
fun addHeader(name: String, value: String) = apply {
152-
this.httpHeaders = this.httpHeaders.orEmpty() + HttpHeader(name, value)
153-
}
154-
155130
/**
156131
* Set the [WebSocketEngine] to use.
157132
*/
@@ -160,12 +135,11 @@ class WebSocketNetworkTransport private constructor(
160135
}
161136

162137
/**
163-
* The number of milliseconds before a WebSocket with no active operations disconnects.
164-
*
165-
* Default: `60_000`
138+
* @param idleTimeout the duration before a WebSocket with no active operations disconnects or
139+
* null to use the default of 1 minute.
166140
*/
167-
fun idleTimeoutMillis(idleTimeoutMillis: Long?) = apply {
168-
this.idleTimeoutMillis = idleTimeoutMillis
141+
fun idleTimeout(idleTimeout: Duration?) = apply {
142+
this.idleTimeout = idleTimeout
169143
}
170144

171145
/**
@@ -182,22 +156,19 @@ class WebSocketNetworkTransport private constructor(
182156
}
183157

184158
/**
185-
* The interval in milliseconds between two client pings or -1 to disable client pings.
159+
* @param pingInterval the interval between two client pings or null to disable client pings.
186160
* The [WsProtocol] used must also support client pings.
187-
*
188-
* Default: -1
189161
*/
190-
fun pingIntervalMillis(pingIntervalMillis: Long?) = apply {
191-
this.pingIntervalMillis = pingIntervalMillis
162+
fun pingInterval(pingInterval: Duration?) = apply {
163+
this.pingInterval = pingInterval
192164
}
193165

194166
/**
195-
* The maximum number of milliseconds between a "connection_init" message and its acknowledgement
196-
*
197-
* Default: 10_000
167+
* @param connectionAcknowledgeTimeout the maximum duration between a "connection_init" message and its acknowledgement
168+
* or null to use the default of 10 seconds
198169
*/
199-
fun connectionAcknowledgeTimeoutMillis(connectionAcknowledgeTimeoutMillis: Long?) = apply {
200-
this.connectionAcknowledgeTimeoutMillis = connectionAcknowledgeTimeoutMillis
170+
fun connectionAcknowledgeTimeout(connectionAcknowledgeTimeout: Duration?) = apply {
171+
this.connectionAcknowledgeTimeout = connectionAcknowledgeTimeout
201172
}
202173

203174
@ApolloExperimental
@@ -213,11 +184,10 @@ class WebSocketNetworkTransport private constructor(
213184
return WebSocketNetworkTransport(
214185
webSocketEngine = webSocketEngine ?: WebSocketEngine(),
215186
serverUrl = serverUrl ?: error("Apollo: 'serverUrl' is required"),
216-
httpHeaders = httpHeaders.orEmpty(),
217-
idleTimeoutMillis = idleTimeoutMillis ?: 60_000,
187+
idleTimeout = idleTimeout ?: 60.seconds,
218188
wsProtocol = wsProtocol ?: GraphQLWsProtocol { null },
219-
pingIntervalMillis = pingIntervalMillis ?: -1L,
220-
connectionAcknowledgeTimeoutMillis = connectionAcknowledgeTimeoutMillis ?: 10_000L,
189+
pingInterval = pingInterval,
190+
connectionAcknowledgeTimeout = connectionAcknowledgeTimeout ?: 10.seconds,
221191
parserFactory = parserFactory ?: DefaultSubscriptionParserFactory
222192
)
223193
}
@@ -260,10 +230,10 @@ private class DefaultSubscriptionParser<D : Operation.Data>(private val request:
260230
deferredJsonMerger.reset()
261231
}
262232

263-
if (deferredJsonMerger.isEmptyPayload) {
264-
return null
233+
return if (deferredJsonMerger.isEmptyPayload) {
234+
null
265235
} else {
266-
return apolloResponse
236+
apolloResponse
267237
}
268238
}
269239
}

0 commit comments

Comments
 (0)