From cddc2396d9930d728cb8f898ad31354eb0b0c696 Mon Sep 17 00:00:00 2001 From: Pauljd Date: Sun, 1 Nov 2026 19:42:36 +0000 Subject: [PATCH] Recover from slow provider pages during import (0.20.0) The full import stopped at position 65,200 and each retry failed. Gives catalogue pages a longer timeout, retries slow pages at smaller sizes, stops asking for a total after the first page, and reports what happened. Co-Authored-By: Claude Opus 5.5 (1M context) --- VERIFICATION-0.20.0.md | 11 ++++ android/app/build.gradle.kts | 4 +- .../java/tv/orbit/classic/CatalogueImport.kt | 55 ++++++++++++++---- .../java/tv/orbit/classic/CatalogueScreen.kt | 2 +- .../main/java/tv/orbit/classic/EmbyClient.kt | 13 +++-- .../tv/orbit/classic/EmbyConnectionScreen.kt | 7 ++- .../tv/orbit/classic/EmbyPlaybackProtocol.kt | 5 +- .../tv/orbit/classic/SecureMediaDataSource.kt | 2 +- .../tv/orbit/classic/CatalogueImportTest.kt | 35 ++++++++++- .../build-network-brands.cpython-314.pyc | Bin 0 -> 85653 bytes 10 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 VERIFICATION-0.20.0.md create mode 100644 design/channels/__pycache__/build-network-brands.cpython-314.pyc diff --git a/VERIFICATION-0.20.0.md b/VERIFICATION-0.20.0.md new file mode 100644 index 0000000..c43db9b --- /dev/null +++ b/VERIFICATION-0.20.0.md @@ -0,0 +1,11 @@ +# Orbit TV 0.20.0 — import recovery + +Reported on the box: the full import stopped at position 65,200, and each later press failed about 20 seconds in with "could not be reached". The provider's public endpoint answered in about 0.2 seconds from the same connection, so a block on the connection looks unlikely. The app's 15-second read timeout was reported as "could not be reached", so the leading explanation is that deep pages are too slow to answer. That is unconfirmed: nothing recorded the real cause, and one bad record is also possible. + +Changes: catalogue pages get a 60-second read timeout. A timeout now reads "took too long", separately from a failed connection. A timeout, dropped connection or 5xx retries with a smaller page (200, 100, 50, 25) and waits of 5, 10, 15 and 20 seconds, then stops after five tries and names the position. Page size stays reduced for the rest of the run. Rate-limit, login and permission replies still stop at once. Only the first page asks the provider for a total (EnableTotalRecordCount=false afterwards, a parameter not in the published list). The screen reports retries, the slowest page and the page size. Database format is unchanged, so position 65,200 carries over. + +If this still fails, the next step is paging by name (NameStartsWithOrGreater with SortName) instead of by deep offset, which would restart the import. + +Validation: offline assembleDebug, testDebugUnitTest and lintDebug passed; 112 unit tests (108 existing, 4 new), zero failures or errors, no lint errors. Fixture tests cover smaller retries with no missed titles, 5xx against refusal, giving up after five tries with finished pages kept, and first-page-only totals. A real slow provider can only be tested on the box. + +Rollback: reinstall outputs/revision-0.19.0, whose database format is the same, or revert this commit. diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 79e6267..20e1ea4 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -9,8 +9,8 @@ android { applicationId = "tv.orbit.classic" minSdk = 26 targetSdk = 36 - versionCode = 19 - versionName = "0.19.0-full-import" + versionCode = 20 + versionName = "0.20.0-import-recovery" } buildFeatures { compose = true } compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 } diff --git a/android/app/src/main/java/tv/orbit/classic/CatalogueImport.kt b/android/app/src/main/java/tv/orbit/classic/CatalogueImport.kt index 1d7bfec..bc35ab9 100644 --- a/android/app/src/main/java/tv/orbit/classic/CatalogueImport.kt +++ b/android/app/src/main/java/tv/orbit/classic/CatalogueImport.kt @@ -7,7 +7,10 @@ internal data class CatalogueRecord(val id: String, val type: String, val title: val genres: List, val studios: List, val providerIds: Map, val premiere: String, val runtimeMs: Long?, val originalTitle: String = "", val tags: List = emptyList()) internal class CataloguePage(val records: List, val rawCount: Int, val total: Long?) -internal data class CatalogueRun(val pages: Int, val records: Int, val finished: Boolean) +internal data class CatalogueRun(val pages: Int, val records: Int, val finished: Boolean) { + var pageSize = CATALOGUE_PAGE_SIZE + var slowestMs = 0L +} /** Each write is one transaction, so an interrupted import resumes from the last whole page. */ internal interface CatalogueSink { @@ -19,6 +22,10 @@ internal const val CATALOGUE_PAGE_SIZE = 200 internal const val CATALOGUE_PAGES_PER_RUN = 5 internal const val CATALOGUE_PAGES_FULL_RUN = 5_000 internal const val CATALOGUE_PAUSE_MS = 1_500L +internal const val CATALOGUE_MIN_PAGE_SIZE = 25 +internal const val CATALOGUE_MAX_ATTEMPTS = 5 +internal const val CATALOGUE_BACKOFF_MS = 5_000L +internal const val CATALOGUE_READ_TIMEOUT_MS = 60_000 private fun names(array: JSONArray?, limit: Int = 8): List = (0 until minOf(array?.length() ?: 0, 32)).mapNotNull { index -> when (val value = array?.opt(index)) { @@ -47,28 +54,52 @@ private fun catalogueRecord(row: JSONObject): CatalogueRecord? { } /** Oldest first, so titles added during an import land after the current position. */ -internal fun fetchCataloguePage(transport: EmbyTransport, userId: String, token: () -> String, start: Long): CataloguePage { - require(EmbyClient.validId(userId) && start >= 0) - val reply = transport.execute(EmbyRequest("GET", "/Items?UserId=$userId&Recursive=true&IncludeItemTypes=Movie,Series&StartIndex=$start&Limit=$CATALOGUE_PAGE_SIZE&SortBy=DateCreated&SortOrder=Ascending&Fields=Genres,OfficialRating,OriginalTitle,PremiereDate,ProductionYear,ProviderIds,Studios,Tags&EnableImages=false&EnableUserData=false", token = token())) +internal fun fetchCataloguePage(transport: EmbyTransport, userId: String, token: () -> String, start: Long, + limit: Int = CATALOGUE_PAGE_SIZE, withTotal: Boolean = true): CataloguePage { + require(EmbyClient.validId(userId) && start >= 0 && limit in 1..CATALOGUE_PAGE_SIZE) + // Counting the whole library is costly, so only the first page asks for the total. + val count = if (withTotal) "" else "&EnableTotalRecordCount=false" + val reply = transport.execute(EmbyRequest("GET", "/Items?UserId=$userId&Recursive=true&IncludeItemTypes=Movie,Series&StartIndex=$start&Limit=$limit&SortBy=DateCreated&SortOrder=Ascending&Fields=Genres,OfficialRating,OriginalTitle,PremiereDate,ProductionYear,ProviderIds,Studios,Tags&EnableImages=false&EnableUserData=false$count", token = token(), readTimeoutMs = CATALOGUE_READ_TIMEOUT_MS)) EmbyClient.expectSuccess(reply.status, false) val page = EmbyClient.parse(reply.body) val rows = page.optJSONArray("Items") ?: throw EmbyCheckException("The provider did not return a catalogue page.") - val count = minOf(rows.length(), CATALOGUE_PAGE_SIZE) - val records = (0 until count).mapNotNull { rows.optJSONObject(it)?.let(::catalogueRecord) }.distinctBy { it.id } + val rowCount = minOf(rows.length(), limit) + val records = (0 until rowCount).mapNotNull { rows.optJSONObject(it)?.let(::catalogueRecord) }.distinctBy { it.id } val total = if (page.has("TotalRecordCount")) page.optLong("TotalRecordCount", -1).takeIf { it >= 0 } else null - return CataloguePage(records, count, total) + return CataloguePage(records, rowCount, total) } -/** One explicit run, either five pages or the whole library. A rate-limit or login failure stops it; finished pages stay saved. */ +/** + * One explicit run, either five pages or the whole library. A rate-limit or login failure stops it at once. + * A slow or dropped page is retried with smaller pages and a growing wait, then the run stops. Finished pages stay saved. + */ internal fun importCatalogue(transport: EmbyTransport, userId: String, token: () -> String, sink: CatalogueSink, - maxPages: Int = CATALOGUE_PAGES_PER_RUN, pause: () -> Unit = {}, checkActive: () -> Unit = {}, onPage: () -> Unit = {}): CatalogueRun { + maxPages: Int = CATALOGUE_PAGES_PER_RUN, pause: () -> Unit = {}, checkActive: () -> Unit = {}, onPage: () -> Unit = {}, + backoff: (Int) -> Unit = {}, onRetry: (Int) -> Unit = {}): CatalogueRun { require(maxPages in 1..CATALOGUE_PAGES_FULL_RUN) var start = sink.position(userId) var pages = 0 var written = 0 + var size = CATALOGUE_PAGE_SIZE + var failures = 0 + var slowest = 0L + fun result(finished: Boolean) = CatalogueRun(pages, written, finished).also { it.pageSize = size; it.slowestMs = slowest } while (pages < maxPages) { checkActive() - val page = fetchCataloguePage(transport, userId, token, start) + val began = System.currentTimeMillis() + val page = try { + fetchCataloguePage(transport, userId, token, start, size, start == 0L) + } catch (failure: EmbyCheckException) { + if (!failure.retryable) throw failure + if (++failures >= CATALOGUE_MAX_ATTEMPTS) + throw EmbyCheckException("${failure.message} Stopped at position $start after $failures tries, the last asking for $size titles.", retryable = true) + size = maxOf(CATALOGUE_MIN_PAGE_SIZE, size / 2) + onRetry(size) + backoff(failures) + continue + } + failures = 0 + slowest = maxOf(slowest, System.currentTimeMillis() - began) checkActive() val next = start + page.rawCount val finished = page.rawCount == 0 || page.total?.let { next >= it } == true @@ -77,8 +108,8 @@ internal fun importCatalogue(transport: EmbyTransport, userId: String, token: () pages++ written += page.records.size onPage() - if (finished) return CatalogueRun(pages, written, true) + if (finished) return result(true) if (pages < maxPages) pause() } - return CatalogueRun(pages, written, false) + return result(false) } diff --git a/android/app/src/main/java/tv/orbit/classic/CatalogueScreen.kt b/android/app/src/main/java/tv/orbit/classic/CatalogueScreen.kt index 7b7647c..4672002 100644 --- a/android/app/src/main/java/tv/orbit/classic/CatalogueScreen.kt +++ b/android/app/src/main/java/tv/orbit/classic/CatalogueScreen.kt @@ -33,7 +33,7 @@ internal fun CatalogueScreen(summary: CatalogueSummary?, busy: Boolean, canRun: } Column(modifier.fillMaxWidth().background(Navy).padding(18.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { Text("Library import test", color = Yellow, fontSize = 26.sp) - Text("Saves film and series details on this box. Channels and schedules are not changed, and no episodes are read. Importing everything takes about half an hour.", color = Color.White, fontSize = 15.sp) + Text("Saves film and series details on this box. Channels and schedules are not changed, and no episodes are read. Importing everything can take a while, as later pages are slower.", color = Color.White, fontSize = 15.sp) Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { OrbitButton(if (busy) "Importing…" else if (summary?.finished == true) "Import finished" else "Import everything", enabled = canRun && summary?.finished != true, onClick = { onRun(true) }) OrbitButton("Import next 1,000", enabled = canRun && summary?.finished != true, onClick = { onRun(false) }) diff --git a/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt b/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt index e6dbc6c..ca6d5a5 100644 --- a/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt +++ b/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt @@ -7,10 +7,10 @@ import java.net.URL import java.util.UUID import javax.net.ssl.HttpsURLConnection -internal class EmbyCheckException(message: String, val httpStatus: Int? = null) : Exception(message) +internal class EmbyCheckException(message: String, val httpStatus: Int? = null, val retryable: Boolean = false) : Exception(message) internal data class SampleItem(val title: String, val type: String, val minutes: Long?, val format: String, val id: String = "", val durationMs: Long? = minutes?.takeIf { it in 1..(Long.MAX_VALUE / 60_000) }?.times(60_000)) internal data class EmbySample(val items: List, val total: Long?) -internal class EmbyRequest(val method: String, val path: String, val body: String? = null, val token: String? = null) +internal class EmbyRequest(val method: String, val path: String, val body: String? = null, val token: String? = null, val readTimeoutMs: Int? = null) internal class EmbyReply(val status: Int, val body: String) internal fun interface EmbyTransport { fun execute(request: EmbyRequest): EmbyReply } @@ -39,9 +39,9 @@ internal class HttpsEmbyTransport(internal val deviceId: String = UUID.randomUUI connection.requestMethod = request.method connection.instanceFollowRedirects = false connection.connectTimeout = 10_000 - connection.readTimeout = if (request.path == "/Sessions/Logout") 5_000 else 15_000 + connection.readTimeout = request.readTimeoutMs ?: if (request.path == "/Sessions/Logout") 5_000 else 15_000 connection.setRequestProperty("Accept", "application/json") - connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.19.0\"") + connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.20.0\"") request.token?.let { connection.setRequestProperty("X-Emby-Token", it) } if (request.method == "POST") { val bytes = request.body.orEmpty().toByteArray(Charsets.UTF_8) @@ -57,7 +57,8 @@ internal class HttpsEmbyTransport(internal val deviceId: String = UUID.randomUUI return EmbyReply(status, body) } catch (e: EmbyCheckException) { throw e } catch (_: javax.net.ssl.SSLException) { throw EmbyCheckException("The secure connection could not be verified. No insecure fallback was used.") } - catch (_: java.io.IOException) { throw EmbyCheckException("The provider could not be reached. Check your connection and try again.") } + catch (_: java.net.SocketTimeoutException) { throw EmbyCheckException("The provider took too long to answer.", retryable = true) } + catch (_: java.io.IOException) { throw EmbyCheckException("The provider could not be reached. Check your connection and try again.", retryable = true) } finally { connection.disconnect() } } } @@ -130,7 +131,7 @@ internal class EmbyClient(private val transport: EmbyTransport = HttpsEmbyTransp 403 -> throw EmbyCheckException("The provider did not permit this connection or library request.", status) 429 -> throw EmbyCheckException("The provider asked us to slow down. Wait before trying again.", status) in 300..399 -> throw EmbyCheckException("The provider redirected the request. The login was not forwarded to another address.") - else -> throw EmbyCheckException("The provider could not complete this check (HTTP $status).") + else -> throw EmbyCheckException("The provider could not complete this check (HTTP $status).", retryable = status >= 500) } } } diff --git a/android/app/src/main/java/tv/orbit/classic/EmbyConnectionScreen.kt b/android/app/src/main/java/tv/orbit/classic/EmbyConnectionScreen.kt index 3227392..9deffd6 100644 --- a/android/app/src/main/java/tv/orbit/classic/EmbyConnectionScreen.kt +++ b/android/app/src/main/java/tv/orbit/classic/EmbyConnectionScreen.kt @@ -245,9 +245,12 @@ internal fun EmbyConnectionScreen(modifier: Modifier = Modifier, visible: Boolea active.importCatalogue(catalogue, if (everything) CATALOGUE_PAGES_FULL_RUN else CATALOGUE_PAGES_PER_RUN, pause = { Thread.sleep(CATALOGUE_PAUSE_MS) }, checkActive = { context.ensureActive() }, // The summary counts the whole table, so it refreshes every few pages, not on each one. - onPage = { if (++pages % 5 == 0) { val latest = catalogue.summary(); scope.launch { catalogueSummary = latest } } }) + onPage = { if (++pages % 5 == 0) { val latest = catalogue.summary(); scope.launch { catalogueSummary = latest; message = null } } }, + backoff = { attempt -> Thread.sleep(CATALOGUE_BACKOFF_MS * attempt) }, + onRetry = { size -> scope.launch { message = "The provider is slow here. Retrying with $size titles at a time…" } }) } - catalogueRun = "Last run: ${result.records} titles in ${result.pages} pages, ${(System.currentTimeMillis() - started) / 1000} seconds." + message = null + catalogueRun = "Last run: ${result.records} titles in ${result.pages} pages, ${(System.currentTimeMillis() - started) / 1000} seconds. Slowest page ${result.slowestMs / 1000} seconds, ${result.pageSize} titles per page." } catch (cancelled: CancellationException) { throw cancelled } catch (failure: EmbyCheckException) { message = failure.message + " Finished pages are saved." } catch (_: Exception) { message = "The import stopped. Finished pages are saved, and it can carry on later." } diff --git a/android/app/src/main/java/tv/orbit/classic/EmbyPlaybackProtocol.kt b/android/app/src/main/java/tv/orbit/classic/EmbyPlaybackProtocol.kt index 0128255..8b7f3c8 100644 --- a/android/app/src/main/java/tv/orbit/classic/EmbyPlaybackProtocol.kt +++ b/android/app/src/main/java/tv/orbit/classic/EmbyPlaybackProtocol.kt @@ -149,8 +149,9 @@ internal class EmbySampleSession(private val transport: EmbyTransport, private v fun checkMetadataCoverage(checkActive: () -> Unit = {}): List = auditMetadataCoverage(transport, userId, ::currentToken, checkActive) - fun importCatalogue(sink: CatalogueSink, maxPages: Int = CATALOGUE_PAGES_PER_RUN, pause: () -> Unit = {}, checkActive: () -> Unit = {}, onPage: () -> Unit = {}): CatalogueRun = - importCatalogue(transport, userId, ::currentToken, sink, maxPages, pause, checkActive, onPage) + fun importCatalogue(sink: CatalogueSink, maxPages: Int = CATALOGUE_PAGES_PER_RUN, pause: () -> Unit = {}, checkActive: () -> Unit = {}, onPage: () -> Unit = {}, + backoff: (Int) -> Unit = {}, onRetry: (Int) -> Unit = {}): CatalogueRun = + importCatalogue(transport, userId, ::currentToken, sink, maxPages, pause, checkActive, onPage, backoff, onRetry) fun checkAfterDarkMovies(genre: String): List { val found = discoverAfterDarkMovies(transport, userId, ::currentToken, genre) currentToken() diff --git a/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt b/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt index 9fcbb27..3c24087 100644 --- a/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt +++ b/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt @@ -33,7 +33,7 @@ internal class SecureMediaDataSource(private val session: EmbySampleSession) : B next.instanceFollowRedirects = false next.connectTimeout = 10_000 next.readTimeout = 20_000 - next.setRequestProperty("User-Agent", "OrbitTV/0.19.0") + next.setRequestProperty("User-Agent", "OrbitTV/0.20.0") next.setRequestProperty("Accept-Encoding", "identity") session.mediaHeaders(address).forEach { (key, value) -> next.setRequestProperty(key, value) } if (dataSpec.position != 0L || dataSpec.length != C.LENGTH_UNSET.toLong()) { diff --git a/android/app/src/test/java/tv/orbit/classic/CatalogueImportTest.kt b/android/app/src/test/java/tv/orbit/classic/CatalogueImportTest.kt index 0c5975b..c1b74c0 100644 --- a/android/app/src/test/java/tv/orbit/classic/CatalogueImportTest.kt +++ b/android/app/src/test/java/tv/orbit/classic/CatalogueImportTest.kt @@ -18,12 +18,14 @@ class CatalogueImportTest { } private fun row(id: String, type: String = "Movie") = JSONObject().put("Id", id).put("Type", type).put("Name", "Fixture $id") private fun startOf(request: EmbyRequest) = request.path.substringAfter("StartIndex=").substringBefore('&').toInt() + private fun limitOf(request: EmbyRequest) = request.path.substringAfter("Limit=").substringBefore('&').toInt() + private val slow = EmbyCheckException("The provider took too long to answer.", retryable = true) /** A fixture library of [size] rows, answering paging as a server would. */ private fun library(size: Int, requests: MutableList = mutableListOf()) = EmbyTransport { r -> requests += r val start = startOf(r) val rows = JSONArray() - for (i in start until minOf(start + CATALOGUE_PAGE_SIZE, size)) rows.put(row("id-$i", if (i % 5 == 0) "Series" else "Movie")) + for (i in start until minOf(start + limitOf(r), size)) rows.put(row("id-$i", if (i % 5 == 0) "Series" else "Movie")) EmbyReply(200, JSONObject().put("Items", rows).put("TotalRecordCount", size).toString()) } private fun run(transport: EmbyTransport, sink: CatalogueSink, user: String = "fixture-user", checkActive: () -> Unit = {}) = @@ -48,6 +50,37 @@ class CatalogueImportTest { assertTrue(sink.finished); assertEquals(132_544, sink.records.size) assertEquals(requests.map(::startOf), requests.map(::startOf).distinct()) } + @Test fun aSlowPageRetriesSmallerStaysSmallerAndMissesNothing() { + val requests = mutableListOf(); val sink = MemorySink(); val server = library(1000); val retries = mutableListOf(); val waits = mutableListOf() + var failures = 2 + val result = importCatalogue(EmbyTransport { r -> requests += r; if (startOf(r) == 200 && failures-- > 0) throw slow; server.execute(r) }, "fixture-user", { "fixture-token" }, sink, 10, backoff = { waits += it }, onRetry = { retries += it }) + assertEquals(listOf(100, 50), retries); assertEquals(listOf(1, 2), waits); assertEquals(50, result.pageSize) + assertEquals(listOf(200, 200, 100, 50), requests.map(::limitOf).take(4)); assertEquals(listOf(0, 200, 200, 200), requests.map(::startOf).take(4)) + assertEquals(10, result.pages); assertEquals(650L, sink.next) + assertTrue((0 until 650).all { "id-$it" in sink.records }) + } + @Test fun aServerErrorRetriesButRefusalDoesNot() { + val sink = MemorySink(); val server = library(1000); var failed = false + val result = importCatalogue(EmbyTransport { r -> if (!failed) { failed = true; EmbyReply(500, "") } else server.execute(r) }, "fixture-user", { "fixture-token" }, sink, 1) + assertEquals(1, result.pages); assertEquals(100, result.pageSize) + var calls = 0 + try { importCatalogue(EmbyTransport { calls++; EmbyReply(403, "") }, "fixture-user", { "fixture-token" }, MemorySink(), 1); fail("Refusal accepted") } catch (_: EmbyCheckException) { } + assertEquals(1, calls) + } + @Test fun givesUpAfterFiveTriesKeepsFinishedPagesAndSaysWhere() { + val sink = MemorySink(); val server = library(5000); val limits = mutableListOf() + try { + importCatalogue(EmbyTransport { r -> if (startOf(r) >= 400) { limits += limitOf(r); throw slow }; server.execute(r) }, "fixture-user", { "fixture-token" }, sink, 50) + fail("Endless failure accepted") + } catch (failure: EmbyCheckException) { assertTrue(failure.message!!.contains("position 400")) } + assertEquals(listOf(200, 100, 50, 25, 25), limits); assertEquals(400L, sink.next); assertEquals(400, sink.records.size) + } + @Test fun onlyTheFirstPageAsksForATotalAndLaterRunsKeepIt() { + val requests = mutableListOf(); val sink = MemorySink(); val server = library(120_000, requests) + run(server, sink) + assertFalse(requests.first().path.contains("EnableTotalRecordCount")); assertTrue(requests.drop(1).all { it.path.contains("EnableTotalRecordCount=false") }) + assertTrue(requests.all { it.readTimeoutMs == CATALOGUE_READ_TIMEOUT_MS }) + } @Test fun aLaterRunResumesWhereTheLastStopped() { val requests = mutableListOf(); val sink = MemorySink(); val server = library(120_000, requests) run(server, sink); requests.clear() diff --git a/design/channels/__pycache__/build-network-brands.cpython-314.pyc b/design/channels/__pycache__/build-network-brands.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e28721d35c9b067b51dc6e68fd43efaf193aa993 GIT binary patch literal 85653 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 literal 0 HcmV?d00001