feat: track processing start-times + global needs-input set for activity monitor
This commit is contained in:
parent
7d9d4fa2bc
commit
9c2ac65635
1 changed files with 49 additions and 0 deletions
|
|
@ -3,6 +3,10 @@ import { useCallback, useState } from 'react';
|
|||
export function useSessionProtection() {
|
||||
const [activeSessions, setActiveSessions] = useState<Set<string>>(new Set());
|
||||
const [processingSessions, setProcessingSessions] = useState<Set<string>>(new Set());
|
||||
// sessionId -> epoch ms when processing began (for the live elapsed timer)
|
||||
const [processingStartTimes, setProcessingStartTimes] = useState<Map<string, number>>(new Map());
|
||||
// sessions waiting on the user (permission / AskUserQuestion pending)
|
||||
const [needsInputSessions, setNeedsInputSessions] = useState<Set<string>>(new Set());
|
||||
|
||||
const markSessionAsActive = useCallback((sessionId?: string | null) => {
|
||||
if (!sessionId) {
|
||||
|
|
@ -30,6 +34,16 @@ export function useSessionProtection() {
|
|||
}
|
||||
|
||||
setProcessingSessions((prev) => new Set([...prev, sessionId]));
|
||||
setProcessingStartTimes((prev) => {
|
||||
// Preserve an existing start time so the elapsed timer doesn't reset on
|
||||
// repeated marks for the same run.
|
||||
if (prev.has(sessionId)) {
|
||||
return prev;
|
||||
}
|
||||
const next = new Map(prev);
|
||||
next.set(sessionId, Date.now());
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const markSessionAsNotProcessing = useCallback((sessionId?: string | null) => {
|
||||
|
|
@ -42,14 +56,49 @@ export function useSessionProtection() {
|
|||
next.delete(sessionId);
|
||||
return next;
|
||||
});
|
||||
setProcessingStartTimes((prev) => {
|
||||
if (!prev.has(sessionId)) {
|
||||
return prev;
|
||||
}
|
||||
const next = new Map(prev);
|
||||
next.delete(sessionId);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const markSessionAsNeedsInput = useCallback((sessionId?: string | null) => {
|
||||
if (!sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
setNeedsInputSessions((prev) => new Set([...prev, sessionId]));
|
||||
}, []);
|
||||
|
||||
const clearSessionNeedsInput = useCallback((sessionId?: string | null) => {
|
||||
if (!sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
setNeedsInputSessions((prev) => {
|
||||
if (!prev.has(sessionId)) {
|
||||
return prev;
|
||||
}
|
||||
const next = new Set(prev);
|
||||
next.delete(sessionId);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
return {
|
||||
activeSessions,
|
||||
processingSessions,
|
||||
processingStartTimes,
|
||||
needsInputSessions,
|
||||
markSessionAsActive,
|
||||
markSessionAsInactive,
|
||||
markSessionAsProcessing,
|
||||
markSessionAsNotProcessing,
|
||||
markSessionAsNeedsInput,
|
||||
clearSessionNeedsInput,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue