@camstack/addon-post-analysis 1.2.302 → 1.2.303
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.
|
@@ -67320,6 +67320,22 @@ function messageOf(err) {
|
|
|
67320
67320
|
function isDetailNotAttachedRefusal(err) {
|
|
67321
67321
|
return messageOf(err).includes(DETAIL_NOT_ATTACHED_MARKER);
|
|
67322
67322
|
}
|
|
67323
|
+
/**
|
|
67324
|
+
* The runner's TYPED handle-expired refusal (D688): the frame handle a dispatch
|
|
67325
|
+
* named is past the native lease age bound, and the registry will refuse it on
|
|
67326
|
+
* every later ask. TWIN of `addon-pipeline/src/pipeline-runner/detail-park.ts`
|
|
67327
|
+
* `DETAIL_HANDLE_EXPIRED_MARKER` — keep the two identical.
|
|
67328
|
+
*
|
|
67329
|
+
* Why the dispatcher cares: unlike not-attached this is about ONE handle, not
|
|
67330
|
+
* the session — the parked frame still serves — but the handle itself is
|
|
67331
|
+
* finished. Naming it again (next tick, or through the native-strict crop rung)
|
|
67332
|
+
* can only be refused again; on the live fleet that was ~7 refusals per handle.
|
|
67333
|
+
*/
|
|
67334
|
+
var DETAIL_HANDLE_EXPIRED_MARKER = "runDetailSubtree-refused:handle-expired";
|
|
67335
|
+
/** Did this `runDetailSubtree` error carry the runner's handle-expired marker? */
|
|
67336
|
+
function isDetailHandleExpiredRefusal(err) {
|
|
67337
|
+
return messageOf(err).includes(DETAIL_HANDLE_EXPIRED_MARKER);
|
|
67338
|
+
}
|
|
67323
67339
|
//#endregion
|
|
67324
67340
|
//#region src/pipeline-analytics/detail-scheduler.ts
|
|
67325
67341
|
/** Default backoff/period when a step's cadence omits `minIntervalMs`. */
|
|
@@ -67776,6 +67792,7 @@ var TrackDetailDispatcher = class {
|
|
|
67776
67792
|
className: frame.className
|
|
67777
67793
|
};
|
|
67778
67794
|
const steps = composeDetailSteps(req, (trackId) => this.deps.hasTrackLabel?.(trackId) ?? false);
|
|
67795
|
+
let handleRefused = false;
|
|
67779
67796
|
if (frame.frameHandle !== void 0) try {
|
|
67780
67797
|
const primary = await this.deps.runDetailSubtree({
|
|
67781
67798
|
deviceId,
|
|
@@ -67789,7 +67806,10 @@ var TrackDetailDispatcher = class {
|
|
|
67789
67806
|
this.warnNotAttachedThrottled(deviceId, dev, req);
|
|
67790
67807
|
return null;
|
|
67791
67808
|
}
|
|
67792
|
-
|
|
67809
|
+
if (isDetailHandleExpiredRefusal(err)) {
|
|
67810
|
+
handleRefused = true;
|
|
67811
|
+
this.retireRefusedHandle(deviceId, dev, req, frame);
|
|
67812
|
+
} else this.deps.logger.debug("detail primary call failed — trying frame fallback", {
|
|
67793
67813
|
tags: { deviceId },
|
|
67794
67814
|
meta: {
|
|
67795
67815
|
trackId: req.trackId,
|
|
@@ -67839,7 +67859,7 @@ var TrackDetailDispatcher = class {
|
|
|
67839
67859
|
}
|
|
67840
67860
|
});
|
|
67841
67861
|
}
|
|
67842
|
-
if (this.deps.captureCropBase64 !== void 0) try {
|
|
67862
|
+
if (this.deps.captureCropBase64 !== void 0 && frame.frameHandle !== void 0 && !handleRefused) try {
|
|
67843
67863
|
const cropJpeg = await this.deps.captureCropBase64(frame);
|
|
67844
67864
|
if (cropJpeg !== null) {
|
|
67845
67865
|
const retry = await this.deps.runDetailSubtree({
|
|
@@ -67868,6 +67888,35 @@ var TrackDetailDispatcher = class {
|
|
|
67868
67888
|
return null;
|
|
67869
67889
|
}
|
|
67870
67890
|
/**
|
|
67891
|
+
* The runner refused `frame`'s handle as past the lease age bound (D688).
|
|
67892
|
+
* That verdict is final for the handle, so the track's stored association
|
|
67893
|
+
* loses it: later dispatches skip rung 1 and the native-strict crop rung
|
|
67894
|
+
* (both would name the same handle and be refused again — ~7 times per
|
|
67895
|
+
* handle on the live fleet) and go straight to the parked frame, until a
|
|
67896
|
+
* newly OBSERVED frame brings a fresh handle via {@link onFrame}.
|
|
67897
|
+
*
|
|
67898
|
+
* Only the refused handle is dropped: if a newer frame replaced it while the
|
|
67899
|
+
* dispatch was in flight, that one stands. The line is therefore emitted once
|
|
67900
|
+
* per (track, handle) — a concurrent dispatch refused on the same handle
|
|
67901
|
+
* finds it already gone and says nothing.
|
|
67902
|
+
*/
|
|
67903
|
+
retireRefusedHandle(deviceId, dev, req, frame) {
|
|
67904
|
+
const current = dev.tracks.get(req.trackId);
|
|
67905
|
+
if (current === void 0 || current.frameHandle !== frame.frameHandle) return;
|
|
67906
|
+
const { frameHandle: refused, ...withoutHandle } = current;
|
|
67907
|
+
dev.tracks.set(req.trackId, withoutHandle);
|
|
67908
|
+
this.deps.logger.info("detail dispatch: frame handle refused as expired — retired for this track, parked frame only until a fresh observation", {
|
|
67909
|
+
tags: { deviceId },
|
|
67910
|
+
meta: {
|
|
67911
|
+
trackId: req.trackId,
|
|
67912
|
+
stepId: req.stepId,
|
|
67913
|
+
reason: "handle-expired",
|
|
67914
|
+
handle: refused === void 0 ? null : `${refused.shmId}#${refused.slot}#${refused.seq}`,
|
|
67915
|
+
parkedFrameRung: this.deps.captureParkedFrame !== void 0
|
|
67916
|
+
}
|
|
67917
|
+
});
|
|
67918
|
+
}
|
|
67919
|
+
/**
|
|
67871
67920
|
* The typed refusal is EXPECTED for a track that outlives the runner's
|
|
67872
67921
|
* detail park grace (a closing track's last dispatches), so it logs its own
|
|
67873
67922
|
* line — the reason is knowable, unlike the every-rung-missed warn — and
|
|
@@ -67228,6 +67228,22 @@ function messageOf(err) {
|
|
|
67228
67228
|
function isDetailNotAttachedRefusal(err) {
|
|
67229
67229
|
return messageOf(err).includes(DETAIL_NOT_ATTACHED_MARKER);
|
|
67230
67230
|
}
|
|
67231
|
+
/**
|
|
67232
|
+
* The runner's TYPED handle-expired refusal (D688): the frame handle a dispatch
|
|
67233
|
+
* named is past the native lease age bound, and the registry will refuse it on
|
|
67234
|
+
* every later ask. TWIN of `addon-pipeline/src/pipeline-runner/detail-park.ts`
|
|
67235
|
+
* `DETAIL_HANDLE_EXPIRED_MARKER` — keep the two identical.
|
|
67236
|
+
*
|
|
67237
|
+
* Why the dispatcher cares: unlike not-attached this is about ONE handle, not
|
|
67238
|
+
* the session — the parked frame still serves — but the handle itself is
|
|
67239
|
+
* finished. Naming it again (next tick, or through the native-strict crop rung)
|
|
67240
|
+
* can only be refused again; on the live fleet that was ~7 refusals per handle.
|
|
67241
|
+
*/
|
|
67242
|
+
var DETAIL_HANDLE_EXPIRED_MARKER = "runDetailSubtree-refused:handle-expired";
|
|
67243
|
+
/** Did this `runDetailSubtree` error carry the runner's handle-expired marker? */
|
|
67244
|
+
function isDetailHandleExpiredRefusal(err) {
|
|
67245
|
+
return messageOf(err).includes(DETAIL_HANDLE_EXPIRED_MARKER);
|
|
67246
|
+
}
|
|
67231
67247
|
//#endregion
|
|
67232
67248
|
//#region src/pipeline-analytics/detail-scheduler.ts
|
|
67233
67249
|
/** Default backoff/period when a step's cadence omits `minIntervalMs`. */
|
|
@@ -67684,6 +67700,7 @@ var TrackDetailDispatcher = class {
|
|
|
67684
67700
|
className: frame.className
|
|
67685
67701
|
};
|
|
67686
67702
|
const steps = composeDetailSteps(req, (trackId) => this.deps.hasTrackLabel?.(trackId) ?? false);
|
|
67703
|
+
let handleRefused = false;
|
|
67687
67704
|
if (frame.frameHandle !== void 0) try {
|
|
67688
67705
|
const primary = await this.deps.runDetailSubtree({
|
|
67689
67706
|
deviceId,
|
|
@@ -67697,7 +67714,10 @@ var TrackDetailDispatcher = class {
|
|
|
67697
67714
|
this.warnNotAttachedThrottled(deviceId, dev, req);
|
|
67698
67715
|
return null;
|
|
67699
67716
|
}
|
|
67700
|
-
|
|
67717
|
+
if (isDetailHandleExpiredRefusal(err)) {
|
|
67718
|
+
handleRefused = true;
|
|
67719
|
+
this.retireRefusedHandle(deviceId, dev, req, frame);
|
|
67720
|
+
} else this.deps.logger.debug("detail primary call failed — trying frame fallback", {
|
|
67701
67721
|
tags: { deviceId },
|
|
67702
67722
|
meta: {
|
|
67703
67723
|
trackId: req.trackId,
|
|
@@ -67747,7 +67767,7 @@ var TrackDetailDispatcher = class {
|
|
|
67747
67767
|
}
|
|
67748
67768
|
});
|
|
67749
67769
|
}
|
|
67750
|
-
if (this.deps.captureCropBase64 !== void 0) try {
|
|
67770
|
+
if (this.deps.captureCropBase64 !== void 0 && frame.frameHandle !== void 0 && !handleRefused) try {
|
|
67751
67771
|
const cropJpeg = await this.deps.captureCropBase64(frame);
|
|
67752
67772
|
if (cropJpeg !== null) {
|
|
67753
67773
|
const retry = await this.deps.runDetailSubtree({
|
|
@@ -67776,6 +67796,35 @@ var TrackDetailDispatcher = class {
|
|
|
67776
67796
|
return null;
|
|
67777
67797
|
}
|
|
67778
67798
|
/**
|
|
67799
|
+
* The runner refused `frame`'s handle as past the lease age bound (D688).
|
|
67800
|
+
* That verdict is final for the handle, so the track's stored association
|
|
67801
|
+
* loses it: later dispatches skip rung 1 and the native-strict crop rung
|
|
67802
|
+
* (both would name the same handle and be refused again — ~7 times per
|
|
67803
|
+
* handle on the live fleet) and go straight to the parked frame, until a
|
|
67804
|
+
* newly OBSERVED frame brings a fresh handle via {@link onFrame}.
|
|
67805
|
+
*
|
|
67806
|
+
* Only the refused handle is dropped: if a newer frame replaced it while the
|
|
67807
|
+
* dispatch was in flight, that one stands. The line is therefore emitted once
|
|
67808
|
+
* per (track, handle) — a concurrent dispatch refused on the same handle
|
|
67809
|
+
* finds it already gone and says nothing.
|
|
67810
|
+
*/
|
|
67811
|
+
retireRefusedHandle(deviceId, dev, req, frame) {
|
|
67812
|
+
const current = dev.tracks.get(req.trackId);
|
|
67813
|
+
if (current === void 0 || current.frameHandle !== frame.frameHandle) return;
|
|
67814
|
+
const { frameHandle: refused, ...withoutHandle } = current;
|
|
67815
|
+
dev.tracks.set(req.trackId, withoutHandle);
|
|
67816
|
+
this.deps.logger.info("detail dispatch: frame handle refused as expired — retired for this track, parked frame only until a fresh observation", {
|
|
67817
|
+
tags: { deviceId },
|
|
67818
|
+
meta: {
|
|
67819
|
+
trackId: req.trackId,
|
|
67820
|
+
stepId: req.stepId,
|
|
67821
|
+
reason: "handle-expired",
|
|
67822
|
+
handle: refused === void 0 ? null : `${refused.shmId}#${refused.slot}#${refused.seq}`,
|
|
67823
|
+
parkedFrameRung: this.deps.captureParkedFrame !== void 0
|
|
67824
|
+
}
|
|
67825
|
+
});
|
|
67826
|
+
}
|
|
67827
|
+
/**
|
|
67779
67828
|
* The typed refusal is EXPECTED for a track that outlives the runner's
|
|
67780
67829
|
* detail park grace (a closing track's last dispatches), so it logs its own
|
|
67781
67830
|
* line — the reason is knowable, unlike the every-rung-missed warn — and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-post-analysis",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.303",
|
|
4
4
|
"description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|