Keep watching the job through transient fetch failures; don't freeze the screen
reprocessInPlace's poll loop swallowed fetchJobs failures as an empty list and broke on the resulting missing status, so ONE dropped poll during a 10-minute summarize ended the watch early: chips stayed disabled, the screen showed stale content, and only leaving to the library and back (fresh openDetail fetch) displayed the finished summary — the exact reported symptom. Now only a successful fetch reporting a terminal state ends the loop; transient failures keep polling for ~30s, and a genuinely-lost engine says so in plain words instead of silently stranding the screen. A missing job row on healthy fetches gets 3 grace cycles before giving up (engine rewrites rows mid-requeue).
This commit is contained in:
parent
70483b4cf8
commit
b5836d0fb6
1 changed files with 26 additions and 4 deletions
|
|
@ -1632,11 +1632,30 @@ class DesktopState(private val appDir: File = defaultAppDir()) {
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Poll the target job to a terminal state.
|
// Poll the target job to a terminal state. A job this long
|
||||||
|
// (10+ min = hundreds of polls) WILL hit a transient fetch
|
||||||
|
// failure; treating one as terminal (the old `orEmpty()` →
|
||||||
|
// st == null → break) froze the screen on stale content until
|
||||||
|
// the user left and returned — exactly the reported symptom.
|
||||||
|
// So: only a SUCCESSFUL fetch reporting a terminal state
|
||||||
|
// breaks; failures keep polling up to ~30s of contact loss.
|
||||||
|
var miss = 0
|
||||||
|
var gone = 0
|
||||||
while (true) {
|
while (true) {
|
||||||
delay(2000)
|
delay(2000)
|
||||||
val jobs = runCatching { parseJobs(provider.fetchJobs(remoteId)) }.getOrNull()
|
val fetched = runCatching { parseJobs(provider.fetchJobs(remoteId)) }
|
||||||
.orEmpty()
|
if (fetched.isFailure) {
|
||||||
|
if (++miss >= 15) {
|
||||||
|
d0.error = "Lost contact with the engine while " +
|
||||||
|
"processing — reopen this recording to check."
|
||||||
|
d0.busy = null
|
||||||
|
_detail.value = d0.copy()
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
miss = 0
|
||||||
|
val jobs = fetched.getOrDefault(emptyList())
|
||||||
d0.jobs = jobs
|
d0.jobs = jobs
|
||||||
jobLabel(jobs)?.let { d0.busy = it }
|
jobLabel(jobs)?.let { d0.busy = it }
|
||||||
// Mirror live progress onto the library row too — otherwise
|
// Mirror live progress onto the library row too — otherwise
|
||||||
|
|
@ -1646,7 +1665,10 @@ class DesktopState(private val appDir: File = defaultAppDir()) {
|
||||||
rescanStatuses()
|
rescanStatuses()
|
||||||
_detail.value = d0.copy()
|
_detail.value = d0.copy()
|
||||||
val st = jobs.firstOrNull { it.jobType == job }?.status
|
val st = jobs.firstOrNull { it.jobType == job }?.status
|
||||||
if (st == null || st in TERMINAL) break
|
if (st in TERMINAL) break
|
||||||
|
// Job row missing from a healthy fetch: give it a few
|
||||||
|
// cycles (the engine rewrites rows mid-requeue) then stop.
|
||||||
|
if (st == null && ++gone >= 3) break
|
||||||
}
|
}
|
||||||
setLive(d0.file.name, null)
|
setLive(d0.file.name, null)
|
||||||
rescanStatuses()
|
rescanStatuses()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue