feat(desktop): add monitor scheduler, Playwright CDP layer, and account health
Move monitor-task scheduling authority onto the client with a durable file-backed queue that survives restart, drops stale cross-day tasks, enforces per-platform serialism, and adapts global concurrency from Electron process metrics. Publish tasks keep their existing FIFO. Add a hidden Playwright CDP manager that attaches to Electron Chromium on account session partitions, lets adapters opt into `executionMode: "playwright"`, and leaves the existing hidden WebContentsView path in place for current adapters. Introduce an account-health subsystem with silent probes, projected health/auth states, and IPC invalidation events so the renderer can show accurate auth/probe status and verification timestamps. Server-side, derive and forward title/business_date/scheduler_group_key/ question_text metadata on desktop task events so the local scheduler can defer same-question fan-out before leasing.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { app } from "electron/main";
|
||||
|
||||
import { getProjectedAccountHealth } from "./account-health";
|
||||
import { getProcessMetricsSnapshot } from "./process-metrics";
|
||||
import { getCircuitBreakerState } from "./circuit-breaker";
|
||||
import { collectRecoverySnapshot } from "./crash-recovery";
|
||||
import { getKeepAlivePlan } from "./keep-alive";
|
||||
import { getLeaseManagerSnapshot } from "./lease-manager";
|
||||
import { getMonitorSchedulerSnapshot } from "./monitor-scheduler";
|
||||
import { getHiddenPlaywrightSnapshot } from "./playwright-cdp";
|
||||
import { getRateLimiterSnapshot } from "./rate-limiter";
|
||||
import { getRuntimeControllerSnapshot } from "./runtime-controller";
|
||||
import { getSchedulerState } from "./scheduler";
|
||||
@@ -71,23 +74,35 @@ function createLiveRuntimeSnapshot(controller: ReturnType<typeof getRuntimeContr
|
||||
const accountQueueDepth = controller.tasks.filter((task) =>
|
||||
task.accountId === account.id && ["queued", "in_progress"].includes(task.status),
|
||||
).length;
|
||||
const projected = getProjectedAccountHealth({
|
||||
accountId: account.id,
|
||||
platform: account.platform,
|
||||
health: account.health,
|
||||
verifiedAt: account.verified_at,
|
||||
});
|
||||
|
||||
return {
|
||||
id: account.id,
|
||||
platform: account.platform,
|
||||
displayName: account.display_name,
|
||||
displayName: projected.profile?.displayName ?? account.display_name,
|
||||
platformUid: normalizeAccountPlatformUid(account.platform_uid) || account.platform_uid,
|
||||
avatarUrl: account.avatar_url ?? null,
|
||||
health: account.health,
|
||||
avatarUrl: projected.profile?.avatarUrl ?? account.avatar_url ?? null,
|
||||
health: projected.health,
|
||||
authState: projected.authState,
|
||||
probeState: projected.probeState,
|
||||
authReason: projected.authReason,
|
||||
tags: account.tags,
|
||||
syncVersion: account.sync_version,
|
||||
clientId: account.client_id ?? primaryClientId,
|
||||
partition: sessionHandle?.partition ?? `persist:acc-${account.id}`,
|
||||
partition: projected.partition || sessionHandle?.partition || `persist:acc-${account.id}`,
|
||||
sessionState: isHot ? "hot" : sessionHandle ? "warm" : "cold",
|
||||
lastSyncAt:
|
||||
controller.lastAccountsSyncAt
|
||||
|| parseTimestamp(account.verified_at)
|
||||
|| now,
|
||||
lastVerifiedAt: projected.lastVerifiedAt,
|
||||
lastProbeAt: projected.lastProbeAt,
|
||||
nextProbeAt: projected.nextProbeAt,
|
||||
queueDepth: accountQueueDepth,
|
||||
online: clientOnline,
|
||||
};
|
||||
@@ -150,9 +165,11 @@ function createLiveRuntimeSnapshot(controller: ReturnType<typeof getRuntimeContr
|
||||
lastError: controller.lastError,
|
||||
},
|
||||
scheduler,
|
||||
monitorScheduler: getMonitorSchedulerSnapshot(),
|
||||
sessions,
|
||||
hotViews,
|
||||
hotViewPool: getHotViewPoolPolicy(),
|
||||
playwright: getHiddenPlaywrightSnapshot(),
|
||||
processMetrics: getProcessMetricsSnapshot(),
|
||||
vault: describeVaultBackend(),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user