@@ -9,7 +9,9 @@ import kotlinx.coroutines.CoroutineScope
9
9
import kotlinx.coroutines.Job
10
10
import kotlinx.coroutines.cancel
11
11
import kotlinx.coroutines.channels.Channel
12
+ import kotlinx.coroutines.channels.ClosedSendChannelException
12
13
import kotlinx.coroutines.delay
14
+ import kotlinx.coroutines.job
13
15
import kotlinx.coroutines.launch
14
16
import kotlinx.coroutines.sync.Mutex
15
17
import kotlinx.coroutines.sync.withLock
@@ -68,6 +70,15 @@ public class KrpcConnector(
68
70
69
71
private val dumpLogger by lazy { RpcInternalDumpLoggerContainer .provide() }
70
72
73
+ // prevent errors ping-pong
74
+ private suspend fun sendMessageIgnoreClosure (message : KrpcMessage ) {
75
+ try {
76
+ sendMessage(message)
77
+ } catch (_: ClosedSendChannelException ) {
78
+ // ignore
79
+ }
80
+ }
81
+
71
82
override suspend fun sendMessage (message : KrpcMessage ) {
72
83
if (message is KrpcProtocolMessage .Handshake ) {
73
84
message.pluginParams[KrpcPluginKey .WINDOW_UPDATE ] = " ${config.perCallBufferSize} "
@@ -271,6 +282,13 @@ public class KrpcConnector(
271
282
processMessage(transport.receiveCatching().getOrNull() ? : break )
272
283
}
273
284
}
285
+
286
+ transportScope.coroutineContext.job.invokeOnCompletion {
287
+ receiveHandlers.clear()
288
+ keyLocks.clear()
289
+ serviceSubscriptions.clear()
290
+ sendHandlers.clear()
291
+ }
274
292
}
275
293
276
294
private fun decodeMessage (transportMessage : KrpcTransportMessage ): KrpcMessage ? {
@@ -344,7 +362,7 @@ public class KrpcConnector(
344
362
}
345
363
346
364
is WindowResult .Failure -> {
347
- sendMessage (
365
+ sendMessageIgnoreClosure (
348
366
KrpcProtocolMessage .Failure (
349
367
errorMessage = result.message,
350
368
connectionId = message.connectionId,
@@ -384,13 +402,18 @@ public class KrpcConnector(
384
402
val handler = handlerFor(key)
385
403
386
404
handler.handle(message) { cause ->
405
+ if (message.isException) {
406
+ return @handle
407
+ }
408
+
387
409
val failure = KrpcProtocolMessage .Failure (
388
410
connectionId = message.connectionId,
389
411
errorMessage = " Failed to process $key , error: ${cause?.message} " ,
390
412
failedMessage = message,
391
413
)
392
414
393
- sendMessage(failure)
415
+ // too late for exceptions
416
+ sendMessageIgnoreClosure(failure)
394
417
}
395
418
}?.onFailure {
396
419
if (message.isException) {
@@ -403,7 +426,8 @@ public class KrpcConnector(
403
426
failedMessage = message,
404
427
)
405
428
406
- sendMessage(failure)
429
+ // too late for exceptions
430
+ sendMessageIgnoreClosure(failure)
407
431
}?.onClosed {
408
432
// do nothing; it's a service message, meaning that the service is dead
409
433
}
@@ -424,6 +448,10 @@ public class KrpcConnector(
424
448
}
425
449
426
450
val result = handler.handle(message) { initialCause ->
451
+ if (message.isException) {
452
+ return @handle
453
+ }
454
+
427
455
val cause = illegalStateException(
428
456
message = " Failed to process call ${message.callId} for service ${message.serviceType} " ,
429
457
cause = initialCause,
0 commit comments