mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-16 17:40:43 +00:00
fix(gateway): recover stale session lanes
This commit is contained in:
@@ -51,6 +51,15 @@ type LaneState = {
|
||||
generation: number;
|
||||
};
|
||||
|
||||
export type CommandLaneSnapshot = {
|
||||
lane: string;
|
||||
queuedCount: number;
|
||||
activeCount: number;
|
||||
maxConcurrent: number;
|
||||
draining: boolean;
|
||||
generation: number;
|
||||
};
|
||||
|
||||
type ActiveTaskWaiter = {
|
||||
activeTaskIds: Set<number>;
|
||||
resolve: (value: { drained: boolean }) => void;
|
||||
@@ -287,6 +296,29 @@ export function getQueueSize(lane: string = CommandLane.Main) {
|
||||
return getLaneDepth(state);
|
||||
}
|
||||
|
||||
export function getCommandLaneSnapshot(lane: string = CommandLane.Main): CommandLaneSnapshot {
|
||||
const resolved = normalizeLane(lane);
|
||||
const state = getQueueState().lanes.get(resolved);
|
||||
if (!state) {
|
||||
return {
|
||||
lane: resolved,
|
||||
queuedCount: 0,
|
||||
activeCount: 0,
|
||||
maxConcurrent: 1,
|
||||
draining: false,
|
||||
generation: 0,
|
||||
};
|
||||
}
|
||||
return {
|
||||
lane: resolved,
|
||||
queuedCount: state.queue.length,
|
||||
activeCount: state.activeTaskIds.size,
|
||||
maxConcurrent: state.maxConcurrent,
|
||||
draining: state.draining,
|
||||
generation: state.generation,
|
||||
};
|
||||
}
|
||||
|
||||
export function getTotalQueueSize() {
|
||||
let total = 0;
|
||||
for (const s of getQueueState().lanes.values()) {
|
||||
@@ -309,6 +341,28 @@ export function clearCommandLane(lane: string = CommandLane.Main) {
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a single lane back to idle and immediately pump any queued entries.
|
||||
* Used only by recovery paths after the owner has already attempted to abort
|
||||
* the active work; stale completions from the previous generation are ignored.
|
||||
*/
|
||||
export function resetCommandLane(lane: string = CommandLane.Main): number {
|
||||
const cleaned = normalizeLane(lane);
|
||||
const state = getQueueState().lanes.get(cleaned);
|
||||
if (!state) {
|
||||
return 0;
|
||||
}
|
||||
const released = state.activeTaskIds.size;
|
||||
state.generation += 1;
|
||||
state.activeTaskIds.clear();
|
||||
state.draining = false;
|
||||
if (state.queue.length > 0) {
|
||||
drainLane(cleaned);
|
||||
}
|
||||
notifyActiveTaskWaiters();
|
||||
return released;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test-only hard reset that discards all queue state, including preserved
|
||||
* queued work from previous generations. Use this when a suite needs an
|
||||
|
||||
Reference in New Issue
Block a user