-
Notifications
You must be signed in to change notification settings - Fork 3.5k
fix(engine): realistic worker memory budget + sizing/feedback telemetry #2723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { describe, expect, it } from "vitest"; | ||
| import { buildTelemetryJoinKeys } from "./feedback.js"; | ||
|
|
||
| describe("buildTelemetryJoinKeys", () => { | ||
| it("emits fid + tid and omits renders when the ring is empty", () => { | ||
| const keys = buildTelemetryJoinKeys({ | ||
| feedbackId: "feedback-uuid", | ||
| anonymousId: "install-uuid", | ||
| }); | ||
| expect(keys).toBe("fid=feedback-uuid tid=install-uuid"); | ||
| }); | ||
|
|
||
| it("appends recent render ids newest-last with a ! marking failed renders", () => { | ||
| const keys = buildTelemetryJoinKeys({ | ||
| feedbackId: "f", | ||
| anonymousId: "t", | ||
| recentRenders: [ | ||
| { id: "render-a", at: "2026-07-21T00:00:00Z", ok: true }, | ||
| { id: "render-b", at: "2026-07-21T01:00:00Z", ok: false }, | ||
| ], | ||
| }); | ||
| expect(keys).toBe("fid=f tid=t renders=render-a,render-b!"); | ||
| }); | ||
|
|
||
| it("stays within the backend env cap for a full ring of uuid render ids", () => { | ||
| const uuid = "01234567-89ab-cdef-0123-456789abcdef"; | ||
| const keys = buildTelemetryJoinKeys({ | ||
| feedbackId: uuid, | ||
| anonymousId: uuid, | ||
| recentRenders: Array.from({ length: 5 }, (_, i) => ({ | ||
| id: uuid, | ||
| at: "2026-07-21T00:00:00Z", | ||
| ok: i % 2 === 0, | ||
| })), | ||
| }); | ||
| // submitFeedback caps env at 500 chars; the doctor summary consumes ~100. | ||
| expect(keys.length).toBeLessThan(400); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,6 +149,17 @@ export function trackRenderComplete( | |
| /** Authoring workflow skill that drove this render (e.g. "product-launch-video"). */ | ||
| authoringSkill?: string; | ||
| workers?: number; | ||
| // Worker auto-sizing provenance (RenderPerfSummary.workerSizing). Answers | ||
| // "why N workers?" fleet-wide, and validates the advisory per-worker heap | ||
| // budget before it's enforced (field OOM: 6 auto workers on a 24GB/4GB-heap | ||
| // machine — see computeWorkerSizing in @hyperframes/engine). | ||
| workersBoundBy?: string; | ||
| workersCpuBased?: number; | ||
| workersMemoryBased?: number; | ||
| workersHeapBased?: number; | ||
| workersFrameBased?: number; | ||
| workersHeapLimitMb?: number; | ||
| workersExceedHeapAdvisory?: boolean; | ||
| docker: boolean; | ||
| gpu: boolean; | ||
| // Static-frame dedup outcome (opt-out HF_STATIC_DEDUP=false). Undefined on | ||
|
|
@@ -245,6 +256,13 @@ export function trackRenderComplete( | |
| quality: props.quality, | ||
| authoring_skill: props.authoringSkill, | ||
| workers: props.workers, | ||
| workers_bound_by: props.workersBoundBy, | ||
| workers_cpu_based: props.workersCpuBased, | ||
| workers_memory_based: props.workersMemoryBased, | ||
| workers_heap_based: props.workersHeapBased, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 Concern — telemetry prop pass-through not test-locked. Fields
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in c6462a0 — |
||
| workers_frame_based: props.workersFrameBased, | ||
| workers_heap_limit_mb: props.workersHeapLimitMb, | ||
| workers_exceed_heap_advisory: props.workersExceedHeapAdvisory, | ||
| docker: props.docker, | ||
| gpu: props.gpu, | ||
| static_dedup_enabled: props.staticDedupEnabled, | ||
|
|
@@ -609,6 +627,14 @@ export function trackRenderFeedback(props: { | |
| renderDurationMs?: number; | ||
| comment?: string; | ||
| doctorSummary?: string; | ||
| /** | ||
| * Join key shared with the forwarded feedback report (Slack/backend): the | ||
| * same uuid rides in the report's env string as `fid=…`, so a wild report | ||
| * resolves to exactly one PostHog "survey sent" event and vice versa. | ||
| */ | ||
| feedbackId?: string; | ||
| /** render_job_id values of this install's recent renders (newest last). */ | ||
| recentRenderIds?: string[]; | ||
| }): void { | ||
| trackEvent("survey sent", { | ||
| $survey_id: "render_satisfaction", | ||
|
|
@@ -617,6 +643,11 @@ export function trackRenderFeedback(props: { | |
| ...(props.comment ? { $survey_response_2: props.comment } : {}), | ||
| ...(props.renderDurationMs !== undefined ? { render_duration_ms: props.renderDurationMs } : {}), | ||
| ...(props.doctorSummary ? { doctor_summary: props.doctorSummary } : {}), | ||
| ...(props.feedbackId ? { feedback_id: props.feedbackId } : {}), | ||
| // Comma-joined: EventProperties values are scalars only. | ||
| ...(props.recentRenderIds?.length | ||
| ? { recent_render_ids: props.recentRenderIds.join(",") } | ||
| : {}), | ||
| }); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Nit — read-modify-write lost-update on concurrent CLIs. The comment above (L112) acknowledges this: 'narrows, but does not eliminate, lost updates against a concurrent CLI process.' In practice the impact is small — a single render's id may be missing from the ring if two
hyperframes renderinvocations write within the same read-modify window. Feedback still works because the join keys carry other ids in the ring plusfeedback_id/tid. Fine as-is; noting for reader awareness in case a future user reports 'my last render isn't in the join keys.' — Rames D JussoThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, leaving as-is — same read-modify-write posture as the existing trial counters, and a dropped ring entry degrades to a slightly less complete join (fid/tid still resolve the install).