@volter/blender-engine 0.1.64 → 0.1.65

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/browser/runtime.ts +14 -4
  2. package/package.json +1 -1
@@ -118,6 +118,9 @@ export interface BlenderCallMetrics {
118
118
  readonly maxCallMs: number | null;
119
119
  /** Operation and load boundary owning the longest request; no payload data. */
120
120
  readonly maxCallLabel?: string | null;
121
+ /** Current cooperative phase and count of settled wire requests; sampled, not pushed per unit. */
122
+ readonly currentPhase?: string | null;
123
+ readonly completedCalls?: number;
121
124
  /** Calls whose duration passed 5s, counting outstanding ones already past it. */
122
125
  readonly callsOver5s: number;
123
126
  /** The same at 30s — a call this side of it is slow, past it is a wedge. */
@@ -168,7 +171,7 @@ export class BlenderRuntime {
168
171
  readonly #callLabels = new Map<number, string>();
169
172
  #loadBoundary = "engine-start";
170
173
  #maxCompletedLabel: string | null = null;
171
- readonly #callWork = new Map<number, () => void>();
174
+ readonly #operationWork = new Set<() => void>();
172
175
  #lastCallMs: number | null = null;
173
176
  #maxCompletedMs = 0;
174
177
  #completedOver5s = 0;
@@ -499,6 +502,7 @@ export class BlenderRuntime {
499
502
  for (const id of [...this.#pending.keys()]) this.#settled(id);
500
503
  for (const pending of this.#pending.values()) pending.reject(error);
501
504
  this.#pending.clear();
505
+ for (const end of this.#operationWork) end();
502
506
  }
503
507
 
504
508
  /**
@@ -534,6 +538,8 @@ export class BlenderRuntime {
534
538
  // different claim from "no call has happened yet".
535
539
  maxCallMs: this.#lastCallMs === null && oldest === null ? null : Math.round(max),
536
540
  maxCallLabel: maxLabel,
541
+ currentPhase: this.#acceptedRequests ? this.#loadBoundary : null,
542
+ completedCalls: this.#completedCalls,
537
543
  callsOver5s: over5,
538
544
  callsOver30s: over30,
539
545
  lastCallWindow: this.#lastCallWindow,
@@ -543,13 +549,12 @@ export class BlenderRuntime {
543
549
 
544
550
  /** Close a call's window, whether it answered, threw, or was terminated. */
545
551
  #settled(id: number): void {
546
- this.#callWork.get(id)?.();
547
- this.#callWork.delete(id);
548
552
  const started = this.#callStarts.get(id);
549
553
  if (started === undefined) return;
550
554
  this.#callStarts.delete(id);
551
555
  const label = this.#callLabels.get(id) ?? null;
552
556
  this.#callLabels.delete(id);
557
+ this.#completedCalls++;
553
558
  const elapsed = performance.now() - started;
554
559
  this.#lastCallMs = elapsed;
555
560
  if (elapsed > this.#maxCompletedMs) { this.#maxCompletedMs = elapsed; this.#maxCompletedLabel = label; }
@@ -559,14 +564,19 @@ export class BlenderRuntime {
559
564
  this.#lastCallWindow = { start: started, end: started + elapsed };
560
565
  }
561
566
 
567
+ #completedCalls = 0;
562
568
  #acceptedRequests = 0;
563
569
  #requestTail: Promise<void> = Promise.resolve();
564
570
  #request(request: Request, shutdown = false): Promise<unknown> {
565
571
  if (this.#terminated || (this.#stopping && !shutdown))
566
572
  return Promise.reject(new Error('The Blender session is stopping or terminated'));
567
573
  const began = performance.now();
574
+ let endWork = () => {};
568
575
  this.#acceptedRequests++;
569
576
  const answer = this.#requestTail.then(async () => {
577
+ const finishWork = this.#work(`running worker ${request.op}`);
578
+ endWork = () => { if (this.#operationWork.delete(endWork)) finishWork(); };
579
+ this.#operationWork.add(endWork);
570
580
  this.#loadBoundary = request.op;
571
581
  let result = await this.#wireRequest(request) as PullResult<unknown>;
572
582
  while (result?.load === 'continue') {
@@ -576,6 +586,7 @@ export class BlenderRuntime {
576
586
  return result?.load === 'done' ? result.value : result;
577
587
  }).finally(() => {
578
588
  this.#acceptedRequests--;
589
+ endWork();
579
590
  const totalMs = Math.round(performance.now() - began);
580
591
  try { if (totalMs >= 1000) this.#options.log?.('log', `@@VOLTER-WORK op=${request.op} totalMs=${totalMs}`); } catch { /* diagnostics cannot poison the queue */ }
581
592
  });
@@ -592,7 +603,6 @@ export class BlenderRuntime {
592
603
  this.#callStarts.set(id, started);
593
604
  this.#callLabels.set(id, request.op === "load-next" ? `load-next after ${this.#loadBoundary}` : request.op);
594
605
  this.#lastCallWindow = { start: started, end: null };
595
- this.#callWork.set(id, this.#work(`waiting for worker ${request.op}`));
596
606
  try {
597
607
  this.#worker.postMessage({ ...request, id });
598
608
  } catch (error) {
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.64",
5
+ "version": "0.1.65",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },