Support concurrent heartbeat runs with maxConcurrentRuns policy
Add per-agent maxConcurrentRuns (1-10) controlling how many runs execute simultaneously. Implements agent-level start lock, optimistic claim-then-execute flow, atomic token accounting via SQL expressions, and proper status resolution when parallel runs finish. Updates UI config form, live run count display, and SSE invalidation to avoid unnecessary refetches on run event streams. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ function invalidateHeartbeatQueries(
|
||||
companyId: string,
|
||||
payload: Record<string, unknown>,
|
||||
) {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.liveRuns(companyId) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(companyId) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.agents.list(companyId) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.dashboard(companyId) });
|
||||
@@ -100,11 +101,15 @@ function handleLiveEvent(
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type === "heartbeat.run.queued" || event.type === "heartbeat.run.status" || event.type === "heartbeat.run.event") {
|
||||
if (event.type === "heartbeat.run.queued" || event.type === "heartbeat.run.status") {
|
||||
invalidateHeartbeatQueries(queryClient, expectedCompanyId, payload);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type === "heartbeat.run.event") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type === "agent.status") {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.agents.list(expectedCompanyId) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.dashboard(expectedCompanyId) });
|
||||
|
||||
Reference in New Issue
Block a user