feat(desktop): add hot view retain/release lifecycle and process metrics
Replace single-shot acquireHotView with retainHotView/releaseHotView plus a minute-level reaper that closes views idle beyond 5 minutes and never evicts a view while it still has live retainers. Wrap adapter calls in try/finally so a failing publish/query still releases the view. Sample process metrics every minute and expose hot-view policy and process snapshot via the runtime snapshot for diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
normalizeAccountPlatformUid,
|
||||
sameAccountPlatformUid,
|
||||
} from "../shared/account-identity";
|
||||
import { acquireHotView } from "./view-pool";
|
||||
import { releaseHotView, retainHotView } from "./view-pool";
|
||||
import { getLeaseManagerSnapshot, noteLeaseExtended, noteLeaseReleased, setActiveLease } from "./lease-manager";
|
||||
import {
|
||||
initScheduler,
|
||||
@@ -939,25 +939,29 @@ async function executeTaskAdapter(
|
||||
const viewHandle =
|
||||
adapter.executionMode === "session" || adapter.executionMode === "playwright"
|
||||
? null
|
||||
: acquireHotView(task.accountId || task.id);
|
||||
: retainHotView(task.accountId || task.id);
|
||||
|
||||
const result = await adapter.publish(
|
||||
{
|
||||
taskId: task.id,
|
||||
accountId: task.accountId || task.id,
|
||||
session: sessionHandle.session,
|
||||
view: viewHandle?.view ?? null,
|
||||
signal,
|
||||
phase: "initial",
|
||||
article: await loadPublishArticle(task),
|
||||
reportProgress(stage: string) {
|
||||
updateTaskProgress(task.id, `publish adapter progress: ${stage}`);
|
||||
try {
|
||||
return await adapter.publish(
|
||||
{
|
||||
taskId: task.id,
|
||||
accountId: task.accountId || task.id,
|
||||
session: sessionHandle.session,
|
||||
view: viewHandle?.view ?? null,
|
||||
signal,
|
||||
phase: "initial",
|
||||
article: await loadPublishArticle(task),
|
||||
reportProgress(stage: string) {
|
||||
updateTaskProgress(task.id, `publish adapter progress: ${stage}`);
|
||||
},
|
||||
},
|
||||
},
|
||||
payload,
|
||||
);
|
||||
|
||||
return result;
|
||||
payload,
|
||||
);
|
||||
} finally {
|
||||
if (viewHandle) {
|
||||
releaseHotView(viewHandle.accountId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const adapter = selectMonitorAdapter(task.platform);
|
||||
@@ -968,24 +972,28 @@ async function executeTaskAdapter(
|
||||
const viewHandle =
|
||||
adapter.executionMode === "session" || adapter.executionMode === "playwright"
|
||||
? null
|
||||
: acquireHotView(task.accountId || task.id);
|
||||
: retainHotView(task.accountId || task.id);
|
||||
|
||||
const result = await adapter.query(
|
||||
{
|
||||
taskId: task.id,
|
||||
accountId: task.accountId || task.id,
|
||||
session: sessionHandle.session,
|
||||
view: viewHandle?.view ?? null,
|
||||
signal,
|
||||
phase: "initial",
|
||||
reportProgress(stage: string) {
|
||||
updateTaskProgress(task.id, `monitor adapter progress: ${stage}`);
|
||||
try {
|
||||
return await adapter.query(
|
||||
{
|
||||
taskId: task.id,
|
||||
accountId: task.accountId || task.id,
|
||||
session: sessionHandle.session,
|
||||
view: viewHandle?.view ?? null,
|
||||
signal,
|
||||
phase: "initial",
|
||||
reportProgress(stage: string) {
|
||||
updateTaskProgress(task.id, `monitor adapter progress: ${stage}`);
|
||||
},
|
||||
},
|
||||
},
|
||||
payload,
|
||||
);
|
||||
|
||||
return result;
|
||||
payload,
|
||||
);
|
||||
} finally {
|
||||
if (viewHandle) {
|
||||
releaseHotView(viewHandle.accountId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildScaffoldResult(
|
||||
|
||||
Reference in New Issue
Block a user