From b622cad80a4b1f601cc8562a2cc20e5e92c41b5c Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Wed, 29 Jul 2026 04:41:52 +0200 Subject: [PATCH] feat(metrics): run events carry which engine served them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this we cannot tell whether the in-browser path is actually displacing guest boots — the whole point of the dual engine is a number (% of runs that never touched the backend), so the event has to say. --- frontend/src/components/editor/EditorToolbar.tsx | 9 +++++++-- frontend/src/services/metricsService.ts | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/editor/EditorToolbar.tsx b/frontend/src/components/editor/EditorToolbar.tsx index 6038bd16..16d57c20 100644 --- a/frontend/src/components/editor/EditorToolbar.tsx +++ b/frontend/src/components/editor/EditorToolbar.tsx @@ -2,6 +2,7 @@ import { useState, useCallback, useRef, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useEditorStore, chipFileGroupId } from '../../store/useEditorStore'; import { useSimulatorStore, piRerunScript } from '../../store/useSimulatorStore'; +import { decideEngine } from '../../lib/instantEngine'; import { useElectricalStore } from '../../store/useElectricalStore'; import { type VerificationResult } from '../../simulation/verify/circuitVerifier'; import { verifyCircuitFromStore } from '../../simulation/verify/verifyFromStore'; @@ -227,11 +228,12 @@ export const EditorToolbar = ({ // Helper: report a Run event to the backend for analytics. Resolves the // FQBN from the board kind so the backend can group by family/fqbn. const reportRun = useCallback( - (boardKind: BoardKind | undefined) => { + (boardKind: BoardKind | undefined, engine?: 'instant' | 'linux') => { const fqbn = boardKind ? BOARD_KIND_FQBN[boardKind] : null; void reportRunEvent({ project_id: currentProject?.id ?? null, board_fqbn: fqbn ?? null, + engine: engine ?? null, }); }, [currentProject], @@ -824,7 +826,10 @@ export const EditorToolbar = ({ // generic stop-then-boot restart below. if (isPiBoardKind(board?.boardKind ?? '')) { trackRunSimulation(board?.boardKind); - reportRun(board?.boardKind); + reportRun( + board?.boardKind, + decideEngine(activeBoardId, board?.enginePinned).engine, + ); if (board?.running) { // Zombie/edge case (Run is normally disabled while running): // power-cycle for a clean boot. diff --git a/frontend/src/services/metricsService.ts b/frontend/src/services/metricsService.ts index 9ada177d..6a4d1e3c 100644 --- a/frontend/src/services/metricsService.ts +++ b/frontend/src/services/metricsService.ts @@ -12,6 +12,9 @@ api.interceptors.request.use((config) => { export interface RunEventPayload { project_id?: string | null; board_fqbn?: string | null; + /** Which engine took this run — 'instant' (browser) or 'linux' (guest). + * Absent for boards where the question doesn't apply. */ + engine?: 'instant' | 'linux' | null; } export async function reportRunEvent(payload: RunEventPayload): Promise {