diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-03 12:53:35 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-03 14:24:54 +0200 |
| commit | cf8345386996c561f176049b2f83fbd07956995e (patch) | |
| tree | da50f4f3329d519f06b8bf06483b15fa2ae9ca64 /packages/meshbay-android/app/src/test/kotlin/org/meshbay/client | |
| parent | e7d663b76e58354d6a1b58f40624427d5ae660c8 (diff) | |
| download | meshbay-cf8345386996c561f176049b2f83fbd07956995e.tar.gz | |
fix(android): the cast relay spools a receiver's lead to disk
Fragments are 5-10 MB at a film's bitrate; dropped past 8 MB in memory, the
TV froze for their length. Each receiver now reads from its own spool file,
deleted with it; nothing is dropped short of a disk bound.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-android/app/src/test/kotlin/org/meshbay/client')
| -rw-r--r-- | packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt index e11c8c0..1c604d0 100644 --- a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt +++ b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt @@ -17,9 +17,10 @@ import java.net.Socket /** The real relay on loopback, read with a raw socket: what a receiver sees. */ class CastRelayTest { - private val relay = CastRelay { InetAddress.getByName("127.0.0.1") } + private val spool = java.nio.file.Files.createTempDirectory("relay-spool").toFile() + private val relay = CastRelay({ InetAddress.getByName("127.0.0.1") }, spool) - @After fun stop() = relay.stop() + @After fun stop() { relay.stop(); spool.deleteRecursively() } private class Reply(val status: Int, val headers: Map<String, String>, val body: ByteArray) @@ -166,6 +167,32 @@ class CastRelayTest { } } + @Test fun `a receiver far behind loses nothing, and its spool goes with it`() { + // Fragments of 4 MB, ten of them pushed while the receiver has read + // none: far past the 8 MB the desktop drops at, which froze the TV. + val url = relay.start(null, null).getString("url") + val u = java.net.URI(url) + Socket(u.host, u.port).use { s -> + s.getOutputStream().write("GET ${u.rawPath}?${u.rawQuery} HTTP/1.1\r\nHost: x\r\n\r\n".toByteArray()) + Thread.sleep(300) + val big = (0 until 10).map { box("moof", 16 + it) + box("mdat", 4 * 1024 * 1024 + it) } + big.forEach { relay.push(it) } + assertEquals("one spool file for the one receiver", 1, spool.listFiles()!!.size) + val input = DataInputStream(s.getInputStream()) + while (true) { val l = StringBuilder(); while (true) { val c = input.read(); if (c == '\n'.code) break; l.append(c.toChar()) }; if (l.toString().trim().isEmpty()) break } + val body = ByteArrayOutputStream() + val want = big.sumOf { it.size } + while (body.size() < want) { + val size = StringBuilder().also { sb -> while (true) { val c = input.read(); if (c == '\n'.code) break; sb.append(c.toChar()) } }.toString().trim().toInt(16) + val buf = ByteArray(size); input.readFully(buf); body.write(buf); input.read(); input.read() + } + assertArrayEquals("every fragment, in order, none dropped", big.reduce { a, b -> a + b }, body.toByteArray()) + } + Thread.sleep(300) + relay.stop() + assertEquals("the spool is deleted with the receiver", 0, spool.listFiles()!!.size) + } + @Test fun `stopping closes the port`() { val url = relay.start(null, null).getString("url") relay.stop() |