diff options
Diffstat (limited to 'platform-paper')
| -rw-r--r-- | platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueue.kt | 6 | ||||
| -rw-r--r-- | platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueueTest.kt | 15 |
2 files changed, 20 insertions, 1 deletions
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueue.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueue.kt index 0769823..f5e4a28 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueue.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueue.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.SendChannel +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import java.util.UUID import java.util.concurrent.ConcurrentHashMap @@ -34,7 +35,10 @@ class PerPlayerWorkQueue( playerId: UUID, work: suspend () -> Unit, ) { - val accepted = queues.computeIfAbsent(playerId) { startWorker() }.trySend(work).isSuccess + // Checked rather than left to trySend: cancelling the scope kills the worker coroutines but + // does not close their channels, so after shutdown trySend would keep reporting success for + // work nothing will ever read. + val accepted = scope.isActive && queues.computeIfAbsent(playerId) { startWorker() }.trySend(work).isSuccess if (!accepted) { // Reachable once the scope is cancelled at shutdown, or if the player's queue is // released in the same tick as their command. Dropping a message in silence is worse diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueueTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueueTest.kt index 95b7700..2d96cba 100644 --- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueueTest.kt +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueueTest.kt @@ -3,6 +3,7 @@ package dev.m1sk9.lunaticChat.paper import dev.m1sk9.lunaticChat.paper.TestUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout @@ -134,4 +135,18 @@ class PerPlayerWorkQueueTest { assertTrue(logger.severeMessages.any { it.contains("Queued work failed") }) } + + @Test + fun `work submitted after shutdown is reported rather than silently dropped`() { + val logger = TestUtils.TestLogger() + val scope = CoroutineScope(Dispatchers.Default) + val queue = PerPlayerWorkQueue(scope, logger) + val completed = ConcurrentLinkedQueue<String>() + + scope.cancel() + queue.submit(alice) { completed.add("never") } + + assertTrue(completed.isEmpty()) + assertTrue(logger.warningMessages.any { it.contains("their queue is closed") }) + } } |
