@volter/blender-engine 0.1.59 → 0.1.60

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.
@@ -116,6 +116,8 @@ export interface BlenderCallMetrics {
116
116
  * otherwise the worst call this session has ever seen is invisible for
117
117
  * exactly as long as it keeps running. */
118
118
  readonly maxCallMs: number | null;
119
+ /** Operation and load boundary owning the longest request; no payload data. */
120
+ readonly maxCallLabel?: string | null;
119
121
  /** Calls whose duration passed 5s, counting outstanding ones already past it. */
120
122
  readonly callsOver5s: number;
121
123
  /** The same at 30s — a call this side of it is slow, past it is a wedge. */
@@ -163,6 +165,9 @@ export class BlenderRuntime {
163
165
  };
164
166
  /** `performance.now()` at the `postMessage` of every outstanding call. */
165
167
  readonly #callStarts = new Map<number, number>();
168
+ readonly #callLabels = new Map<number, string>();
169
+ #loadBoundary = "engine-start";
170
+ #maxCompletedLabel: string | null = null;
166
171
  readonly #callWork = new Map<number, () => void>();
167
172
  #lastCallMs: number | null = null;
168
173
  #maxCompletedMs = 0;
@@ -265,6 +270,7 @@ export class BlenderRuntime {
265
270
  async #load(request: Extract<Request, { op: 'start' }>): Promise<RuntimeStart> {
266
271
  let result = await this.#request(request) as PullResult<RuntimeStart>;
267
272
  while (result?.load === 'continue') {
273
+ this.#loadBoundary = result.phase;
268
274
  result = await this.#request({ op: 'load-next', token: result.token }) as PullResult<RuntimeStart>;
269
275
  }
270
276
  return result?.load === 'done' ? result.value : result as unknown as RuntimeStart;
@@ -518,12 +524,13 @@ export class BlenderRuntime {
518
524
  metrics(now: number = performance.now()): BlenderCallMetrics {
519
525
  let oldest: number | null = null;
520
526
  let max = this.#maxCompletedMs;
527
+ let maxLabel = this.#maxCompletedLabel;
521
528
  let over5 = this.#completedOver5s;
522
529
  let over30 = this.#completedOver30s;
523
- for (const started of this.#callStarts.values()) {
530
+ for (const [id, started] of this.#callStarts) {
524
531
  const elapsed = now - started;
525
532
  if (oldest === null || elapsed > oldest) oldest = elapsed;
526
- if (elapsed > max) max = elapsed;
533
+ if (elapsed > max) { max = elapsed; maxLabel = this.#callLabels.get(id) ?? null; }
527
534
  if (elapsed >= 5_000) over5 += 1;
528
535
  if (elapsed >= 30_000) over30 += 1;
529
536
  }
@@ -533,6 +540,7 @@ export class BlenderRuntime {
533
540
  // Zero here would mean "no call has ever taken any time", which is a
534
541
  // different claim from "no call has happened yet".
535
542
  maxCallMs: this.#lastCallMs === null && oldest === null ? null : Math.round(max),
543
+ maxCallLabel: maxLabel,
536
544
  callsOver5s: over5,
537
545
  callsOver30s: over30,
538
546
  lastCallWindow: this.#lastCallWindow,
@@ -547,9 +555,11 @@ export class BlenderRuntime {
547
555
  const started = this.#callStarts.get(id);
548
556
  if (started === undefined) return;
549
557
  this.#callStarts.delete(id);
558
+ const label = this.#callLabels.get(id) ?? null;
559
+ this.#callLabels.delete(id);
550
560
  const elapsed = performance.now() - started;
551
561
  this.#lastCallMs = elapsed;
552
- if (elapsed > this.#maxCompletedMs) this.#maxCompletedMs = elapsed;
562
+ if (elapsed > this.#maxCompletedMs) { this.#maxCompletedMs = elapsed; this.#maxCompletedLabel = label; }
553
563
  if (elapsed >= 5_000) this.#completedOver5s += 1;
554
564
  if (elapsed >= 30_000) this.#completedOver30s += 1;
555
565
  if (this.#lastCallWindow !== null && this.#lastCallWindow.start === started)
@@ -564,6 +574,7 @@ export class BlenderRuntime {
564
574
  this.#pending.set(id, { resolve, reject });
565
575
  const started = performance.now();
566
576
  this.#callStarts.set(id, started);
577
+ this.#callLabels.set(id, request.op === "load-next" ? `load-next after ${this.#loadBoundary}` : request.op);
567
578
  this.#lastCallWindow = { start: started, end: null };
568
579
  this.#callWork.set(id, this.#work(`waiting for worker ${request.op}`));
569
580
  try {
package/browser/worker.ts CHANGED
@@ -71,7 +71,8 @@ const pendingPresents = new Map<
71
71
 
72
72
  async function streamToTab(value: unknown): Promise<PresentAnswer> {
73
73
  return await sendFrameValue(value, async chunk => {
74
- await loadCheckpoint?.("frame-transfer");
74
+ const kind = value as { op?: string; mesh?: unknown; image?: unknown };
75
+ await loadCheckpoint?.(`frame-transfer/${kind.op ?? "unknown"}/${kind.mesh !== undefined ? "mesh" : kind.image !== undefined ? "image" : "manifest"}/${chunk.kind}`);
75
76
  const id = ++presentId;
76
77
  return new Promise<PresentAnswer>((resolve, reject) => {
77
78
  pendingPresents.set(id, { resolve, reject });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@volter/blender-engine",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "GPL-3.0-or-later",
5
- "version": "0.1.59",
5
+ "version": "0.1.60",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },