Never double-import a file into the engine: detail Transcribe bails when the pump already owns the file (in-flight check was absent there — mid-upload the mapping sidecar doesn't exist yet, so the upload path created a second server recording; happened live with Gambino Tahoe 11-50). Pump's transcribeFile reuses an existing mapping via /reprocess instead of uploading fresh (a pipeline killed mid-run no longer re-imports as a new recording on next pump). Purged the 11:08 orphan recording from the engine DB.
This commit is contained in:
parent
1f688e79bc
commit
26f7b273ce
1 changed files with 41 additions and 15 deletions
|
|
@ -673,24 +673,39 @@ class DesktopState(private val appDir: File = defaultAppDir()) {
|
|||
return false
|
||||
}
|
||||
return try {
|
||||
val draft = RecordingDraft(
|
||||
id = UUID.randomUUID().toString(),
|
||||
title = f.nameWithoutExtension,
|
||||
createdAtEpochMs = f.lastModified().takeIf { it > 0 }
|
||||
?: System.currentTimeMillis(),
|
||||
durationMs = 0,
|
||||
mime = AUDIO_EXTS[f.extension.lowercase()] ?: "audio/mp4",
|
||||
sourceFile = f,
|
||||
sizeBytes = f.length(),
|
||||
)
|
||||
val ref = provider.upload(draft) {}
|
||||
saveMapping(f, RemoteMapping(ref.key))
|
||||
// If an earlier pass ever uploaded this file, reuse that
|
||||
// recording and re-run the pipeline in place. Uploading again
|
||||
// would create a duplicate server recording (this is exactly
|
||||
// how a file whose pipeline died mid-run got re-imported as a
|
||||
// second row on the next pump).
|
||||
val existing = loadMapping(f)?.recordingId
|
||||
val refKey: String
|
||||
if (existing != null) {
|
||||
refKey = existing
|
||||
runCatching {
|
||||
provider.reprocess(existing, "transcribe")
|
||||
} // 409 "already running" is fine: we adopt it by polling.
|
||||
} else {
|
||||
val draft = RecordingDraft(
|
||||
id = UUID.randomUUID().toString(),
|
||||
title = f.nameWithoutExtension,
|
||||
createdAtEpochMs = f.lastModified().takeIf { it > 0 }
|
||||
?: System.currentTimeMillis(),
|
||||
durationMs = 0,
|
||||
mime = AUDIO_EXTS[f.extension.lowercase()] ?: "audio/mp4",
|
||||
sourceFile = f,
|
||||
sizeBytes = f.length(),
|
||||
)
|
||||
val ref = provider.upload(draft) {}
|
||||
saveMapping(f, RemoteMapping(ref.key))
|
||||
refKey = ref.key
|
||||
}
|
||||
var jobs: List<JobInfo> = emptyList()
|
||||
var polls = 0
|
||||
while (polls < 600) { // up to ~30 min per file at 2s polls
|
||||
polls++
|
||||
delay(2000)
|
||||
jobs = runCatching { parseJobs(provider.fetchJobs(ref.key)) }.getOrNull().orEmpty()
|
||||
jobs = runCatching { parseJobs(provider.fetchJobs(refKey)) }.getOrNull().orEmpty()
|
||||
setLive(f.name, jobProgress(jobs))
|
||||
rescanStatuses()
|
||||
val t = jobs.firstOrNull { it.jobType == "transcribe" }?.status
|
||||
|
|
@ -702,9 +717,9 @@ class DesktopState(private val appDir: File = defaultAppDir()) {
|
|||
it.jobType == "transcribe" && it.status == "failed"
|
||||
}
|
||||
if (transcribeFailed) return false
|
||||
val transcript = runCatching { parseTranscript(provider.fetchTranscript(ref.key)) }
|
||||
val transcript = runCatching { parseTranscript(provider.fetchTranscript(refKey)) }
|
||||
.getOrNull() ?: return false
|
||||
val summary = runCatching { parseSummary(provider.fetchSummary(ref.key)) }.getOrNull()
|
||||
val summary = runCatching { parseSummary(provider.fetchSummary(refKey)) }.getOrNull()
|
||||
saveReport(DetailUi(file = f, transcript = transcript, summary = summary))
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -1377,6 +1392,17 @@ class DesktopState(private val appDir: File = defaultAppDir()) {
|
|||
fun transcribe() {
|
||||
val d = _detail.value ?: return
|
||||
pollJob?.cancel()
|
||||
// The pump (or a detail-run from elsewhere) already owns this
|
||||
// file: never start a second pipeline for it. The upload path
|
||||
// below creates a NEW server recording, and the mapping sidecar
|
||||
// only exists once an upload completes — so mid-flight this is
|
||||
// the only reliable dedup. Show the live row state instead.
|
||||
if (d.file.name in inFlight || isRunning(d.file.name)) {
|
||||
d.busy = _liveProgress.value[d.file.name]?.label ?: "Already queued…"
|
||||
d.error = null
|
||||
_detail.value = d.copy()
|
||||
return
|
||||
}
|
||||
// A file with a known server recording re-runs the pipeline IN
|
||||
// PLACE (the endpoint takes the model override too) — re-uploading
|
||||
// would duplicate the recording server-side. Only never-uploaded
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue