summaryrefslogtreecommitdiff
path: root/platform-paper
diff options
context:
space:
mode:
Diffstat (limited to 'platform-paper')
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueue.kt6
-rw-r--r--platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/PerPlayerWorkQueueTest.kt15
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") })
+ }
}