Add prioritized transport, bounded reconnect, and configurable keepalive
Carry numeric priorities through encrypted RPC and adapter writers with bounded admission. Correct push semantics and socket lifecycle cleanup, expose dispatch gating, and add opt-in connection health. Preserve the WebSocket setup API while allowing applications to override keepalive settings. Enable Android socket publication and document the 0.7.2-SNAPSHOT release workflow.
This commit is contained in:
1 parent
0a52bb5c03
commit
617f22dda1
27 files changed
+1154
-295
No files matched your search
@@ -0,0 +1,65 @@
|
||||
@file:OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class, ExperimentalUnsignedTypes::class)
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.test.*
|
||||
import net.sergeych.crypto2.initCrypto
|
||||
import net.sergeych.kiloparsec.*
|
||||
import kotlin.test.*
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class TransportAdmissionTest {
|
||||
@Test fun readyCallsDoNotAddPollingDelay() = runTest(timeout = 10.seconds) {
|
||||
val ping by command<Int, Int>()
|
||||
val (a, b) = createTestDevice()
|
||||
val local = LocalInterface<Unit>().apply { on(ping) { it } }
|
||||
val client = Transport(a, local, Unit)
|
||||
val server = Transport(b, local, Unit)
|
||||
val jobs = listOf(launch { client.run() }, launch { server.run() })
|
||||
try {
|
||||
val start = currentTime
|
||||
repeat(20) { assertEquals(it, client.call(ping, it)) }
|
||||
assertEquals(0L, currentTime - start, "Ready transports must not impose an artificial per-call delay")
|
||||
} finally { jobs.forEach { it.cancelAndJoin() } }
|
||||
}
|
||||
|
||||
@Test fun successfulPlainPushReturnsNormally() = runTest(timeout = 10.seconds) {
|
||||
val notify by command<Int, Unit>()
|
||||
val received = CompletableDeferred<Int>()
|
||||
val (a, b) = createTestDevice()
|
||||
val client = Transport(a, LocalInterface<Unit>(), Unit)
|
||||
val server = Transport(b, LocalInterface<Unit>().apply { on(notify) { received.complete(it); Unit } }, Unit)
|
||||
val jobs = listOf(launch { client.run() }, launch { server.run() })
|
||||
try {
|
||||
client.push(notify, 7)
|
||||
assertEquals(7, received.await())
|
||||
} finally { jobs.forEach { it.cancelAndJoin() } }
|
||||
}
|
||||
|
||||
@Test fun encryptedPushDoesNotWaitForRemoteHandler() = runTest(timeout = 10.seconds) {
|
||||
initCrypto()
|
||||
val notify by command<Int, Unit>()
|
||||
val ping by command<Int, Int>()
|
||||
val entered = CompletableDeferred<Unit>()
|
||||
val release = CompletableDeferred<Unit>()
|
||||
val ready = CompletableDeferred<Unit>()
|
||||
val (a, b) = createTestDevice()
|
||||
val server = KiloServerConnection(KiloInterface<Unit>().apply {
|
||||
on(notify) { entered.complete(Unit); release.await() }
|
||||
on(ping) { it }
|
||||
}, b, Unit)
|
||||
val client = KiloClientConnection(KiloInterface<Unit>(), a, Unit)
|
||||
val jobs = listOf(launch { server.run() }, launch { client.run { if (it) ready.complete(Unit) } })
|
||||
try {
|
||||
ready.await()
|
||||
val notification = async { client.push(notify, 7) }
|
||||
entered.await()
|
||||
runCurrent()
|
||||
assertTrue(notification.isCompleted, "Push must return before the remote handler finishes")
|
||||
notification.await()
|
||||
assertEquals(9, client.call(ping, 9), "A pending notification must not block ordinary RPC")
|
||||
} finally {
|
||||
release.complete(Unit)
|
||||
jobs.forEach { it.cancelAndJoin() }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user