@muhkoo/theater-transcoder 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/worker.js +10 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muhkoo/theater-transcoder",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Drain a Muhkoo Theater transcode queue with NATIVE ffmpeg. Run it on any machine signed in as you to add transcoding power to your library.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/worker.js CHANGED
@@ -45,11 +45,11 @@ export function startWorker({ client, space, appKey, baseUrl }) {
45
45
  limit: 100,
46
46
  });
47
47
  const now = Date.now();
48
- const cand = rows.find((j) =>
49
- j.input_manifest && (
50
- j.status === "queued" ||
51
- (j.status === "processing" && (!j.heartbeat_at || now - j.heartbeat_at > STALE_MS))
52
- ));
48
+ const isStale = (j) => j.status === "processing" && (!j.heartbeat_at || now - j.heartbeat_at > STALE_MS);
49
+ // Prefer an unclaimed queued job over reclaiming a stale one, so multiple
50
+ // workers spread across DIFFERENT jobs instead of piling onto the same movie.
51
+ const cand = rows.find((j) => j.input_manifest && j.status === "queued")
52
+ || rows.find((j) => j.input_manifest && isStale(j));
53
53
  if (!cand) return null;
54
54
  await patch(cand._id, { status: "processing", worker_id: WORKER_ID, worker_label: WORKER_LABEL, claimed_at: now, heartbeat_at: now });
55
55
  const fresh = await jobs().get(cand._id);
@@ -61,6 +61,10 @@ export function startWorker({ client, space, appKey, baseUrl }) {
61
61
  async function process(job) {
62
62
  activeJobId = job._id;
63
63
  abort = new AbortController();
64
+ // Keep the lease alive for the WHOLE job — including the raw download, which
65
+ // for a big file can exceed STALE_MS with no progress events. Without this a
66
+ // peer treats us as dead mid-download and steals the job (double-transcode).
67
+ const beat = setInterval(() => void patch(job._id, { heartbeat_at: Date.now() }).catch(() => {}), 12_000);
64
68
  let lastBeat = 0;
65
69
  const onProgress = ({ fraction, label }) => {
66
70
  const now = Date.now();
@@ -92,6 +96,7 @@ export function startWorker({ client, space, appKey, baseUrl }) {
92
96
  if (abort.signal.aborted) { log(`job ${job._id} stopped remotely`); }
93
97
  else { await patch(job._id, { status: "error", error: String(e?.message || e) }).catch(() => {}); log(`✗ job ${job._id} failed:`, e?.message || e); }
94
98
  } finally {
99
+ clearInterval(beat);
95
100
  activeJobId = null; abort = null;
96
101
  }
97
102
  }