openvibers/openvibe.media Commits

Reconcile: a virtual clip needs no location of its own (eleven timeline clips were listed as no_canonical_location) (#147)

OP OpenVibers committed 24 days ago · e644ff515e · 2 files, +6 −2

Changes

ddiff --git a/server/objects/reconcile.js b/server/objects/reconcile.js
iindex 1063db1..2c1d1ba 100644
---- a/server/objects/reconcile.js
++++ b/server/objects/reconcile.js
@@@ -8,7 +8,7 @@
* (state present/missing/corrupt, size, verified_at). Never deletes anything.
*
* Detects:
-- * no_canonical_location ready object with no row for its canonical copy
++ * no_canonical_location ready object with no row for its canonical copy (a virtual clip needs none)
* canonical_missing_replica_present canonical copy gone/corrupt while another copy is present
* no_present_copy ready object with no present copy anywhere
* missing_local_file ready object's local location whose file is not on disk
@@@ -144,6 +144,9 @@ async function reconcile({ verify = false, hash = false, head = defaultHead, has
// Per object: is the canonical copy there, and is any copy there at all?
for (const obj of objects) {
if (obj.lifecycle_status !== 'ready') continue;
++ // A virtual clip (F3.5/F3.6) plays its window of the recording's timeline: no location of its own is needed, as
++ // readiness and the verify job already read it. Eleven ready ones were listed as no_canonical_location.
++ if (model.parseJson(obj.metadata, {}).virtual) continue;
const locs = byObject.get(obj.id) || [];
const canon = obj.canonical_provider ? locs.find(l => l.provider === obj.canonical_provider) : null;
const present = locs.filter(l => effective.get(l.id) === 'present');
ddiff --git a/test/objects-reconcile.test.js b/test/objects-reconcile.test.js
iindex 361902c..b1bb6d4 100644
---- a/test/objects-reconcile.test.js
++++ b/test/objects-reconcile.test.js
@@@ -61,6 +61,7 @@ const crypto = require('crypto');
await db.run("UPDATE media_objects SET lifecycle_status = 'deleted' WHERE id = ?", [await objId(2)]); // deleted, but /v/2 still serves it
await d.prepare("INSERT INTO clips (id, app_id, file_path, status) OVERRIDING SYSTEM VALUE VALUES (9, 'live', '/x.webm', 'ready') RETURNING id").run(); // row with no object
const ready = await model.createObject({ app_id: 'live', kind: 'file', lifecycle_status: 'ready' }); // ready object, no location
++ await model.createObject({ app_id: 'live', kind: 'clip', lifecycle_status: 'ready', metadata: { virtual: true } }); // a virtual clip: needs none
// Fake provider: key → size (absent = 404). B2 lost c.webm (R2 still has it) and holds a wrong-size d.webm.
const bucket = { b2: { 'vods/b.webm': 200, 'vods/d.webm': 12345 }, r2: { 'vods/c.webm': 300 } };
@@@ -83,7 +84,7 @@ const crypto = require('crypto');
assert.strictEqual(ro.issues.deleted_publicly_reachable.items[0].table, 'vods');
assert.strictEqual(count(ro, 'missing_projection'), 1);
assert.deepStrictEqual(ro.issues.missing_projection.items[0], { table: 'clips', id: 9 });
-- assert.strictEqual(count(ro, 'no_canonical_location'), 1);
++ assert.strictEqual(count(ro, 'no_canonical_location'), 1, 'the virtual clip plays from its recording\'s timeline: not listed');
assert.strictEqual(ro.issues.no_canonical_location.items[0].object_id, ready);
assert.strictEqual(count(ro, 'canonical_missing_replica_present'), 0, 'remote copies are unverified until --verify');
assert.strictEqual(ro.counts.remote_unverified, 4, 'b2 ×3 + r2 ×1 pending');