Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 2x 2x 2x 2x 1x 1x 3x 3x 3x 2x 3x | /**
* @module parliamentary-data/mcp-retry-queue
* @description Queue orchestrator — drains the file-backed deferred MCP retry
* queue against a live `MCPClient`, classifies each entry as resolved or
* retained, and writes the updated queue back to disk.
*
* Public surface (re-exports for backward compatibility):
* - `MCP_RETRY_QUEUE_SCHEMA`, `DEFAULT_MCP_RETRY_QUEUE_PATH`
* - Types: `MCPRetryQueueEntry`, `MCPRetryQueueFile`, `MCPRetryDrainResult`
* - I/O: `loadMcpRetryQueue`, `saveMcpRetryQueue`
* - Build/merge: `createRetryQueueEntry`, `enqueueRetryEntries`
* - Drain: `drainMcpRetryQueue`
*
* Original 373-line `mcp-retry-queue.ts` was split into this directory; the
* top-level file is now a re-export shim that preserves the historic import
* path used by `tests/mcp-retry-queue.test.ts` and downstream callers.
*
* @author Hack23 AB
* @license Apache-2.0
*/
import type { MCPClient } from '../../mcp-client/client.js';
import type { MCPToolInvocationDiagnostic } from '../../types/mcp.js';
import {
drainDocumentFulltextEntry,
drainVoteringarSearchEntry,
} from './classifier.js';
import {
DEFAULT_MCP_RETRY_QUEUE_PATH,
MCP_RETRY_QUEUE_SCHEMA,
loadMcpRetryQueue,
saveMcpRetryQueue,
type MCPRetryDrainResult,
type MCPRetryQueueEntry,
type MCPRetryQueueFile,
} from './persistence.js';
export {
DEFAULT_MCP_RETRY_QUEUE_PATH,
MCP_RETRY_QUEUE_SCHEMA,
loadMcpRetryQueue,
saveMcpRetryQueue,
type MCPRetryDrainResult,
type MCPRetryQueueEntry,
type MCPRetryQueueFile,
};
export { createRetryQueueEntry, enqueueRetryEntries } from './retry-policy.js';
export async function drainMcpRetryQueue(
client: MCPClient,
options: {
docType?: string | null;
queuePath?: string;
now?: Date;
maxEntries?: number;
} = {},
): Promise<MCPRetryDrainResult> {
const queuePath = options.queuePath ?? DEFAULT_MCP_RETRY_QUEUE_PATH;
const now = options.now ?? new Date();
const queue = loadMcpRetryQueue(queuePath);
const remaining: MCPRetryQueueEntry[] = [];
const resolvedDocuments: Record<string, Record<string, unknown>> = {};
const resolvedVoteringar: Record<string, unknown[]> = {};
const diagnostics: MCPToolInvocationDiagnostic[] = [];
const originalEntryCount = queue.entries.length;
let processed = 0;
let resolved = 0;
let retained = 0;
let expired = 0;
for (const entry of queue.entries) {
Iif (options.docType && entry.docType && entry.docType !== options.docType) {
remaining.push(entry);
continue;
}
Iif (new Date(entry.expiresAt).getTime() < now.getTime()) {
expired++;
continue;
}
Iif (options.maxEntries && processed >= options.maxEntries) {
remaining.push(entry);
continue;
}
processed++;
const outcome =
entry.resourceType === 'document_fulltext'
? await drainDocumentFulltextEntry(client, entry, now)
: await drainVoteringarSearchEntry(client, entry, now);
if (outcome.diagnostic) diagnostics.push(outcome.diagnostic);
if (outcome.kind === 'resolved') {
resolved++;
Eif (outcome.document) resolvedDocuments[entry.resourceId] = outcome.document;
Iif (outcome.voteringar) resolvedVoteringar[entry.resourceId] = outcome.voteringar;
continue;
}
remaining.push(outcome.entry);
retained++;
}
const updatedQueue: MCPRetryQueueFile = {
schema: MCP_RETRY_QUEUE_SCHEMA,
updatedAt: now.toISOString(),
entries: remaining,
};
// Avoid touching the queue file when the queue was already empty AND we
// had nothing to process. Without this guard, every news workflow would
// dirty `data/mcp-retry-queue.json` with a fresh `updatedAt` even when no
// retry work occurred, producing noisy PR diffs and merge conflicts.
const hadWork = originalEntryCount > 0 || processed > 0 || expired > 0 || remaining.length > 0;
if (hadWork) {
saveMcpRetryQueue(updatedQueue, queuePath);
}
return {
queue: updatedQueue,
processed,
resolved,
retained,
expired,
resolvedDocuments,
resolvedVoteringar,
diagnostics,
};
}
|