UNPKG

@dexwox-labs/a2a-server

Version:

TypeScript server implementation for Google's Agent-to-Agent (A2A) protocol - includes Express/WebSocket handlers, request validation and queue management

293 lines 10.2 kB
"use strict"; /** * @module InMemoryQueueManager * @description In-memory implementation of the QueueManager interface * * This module provides an in-memory implementation of the QueueManager interface * for managing event queues in the A2A protocol server. It stores queues and their * statistics in memory, making it suitable for development and testing environments. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InMemoryQueueManager = void 0; const event_queue_1 = require("../agent-execution/event-queue"); const queue_manager_1 = require("./queue-manager"); /** * In-memory implementation of the QueueManager interface * * The InMemoryQueueManager class provides an implementation of the QueueManager * interface that stores queues and their statistics in memory. It's suitable for * development and testing environments, but may not be appropriate for production * use cases with high scalability requirements. * * @example * ```typescript * // Create an in-memory queue manager * const queueManager = new InMemoryQueueManager(); * * // Create a queue for a task * const queue = await queueManager.createOrGet('task-123'); * * // Use the queue * queue.publish({ * type: 'taskCreated', * task: { id: 'task-123', status: 'created' }, * timestamp: Date.now() * }); * ``` */ class InMemoryQueueManager { constructor() { /** Map of task IDs to event queues */ this.queues = new Map(); /** Map of task IDs to queue statistics */ this.stats = new Map(); } /** * Adds a new queue for a task * * This method registers a new event queue for a specific task. * It throws an error if a queue already exists for the task. * * @param taskId - ID of the task to add a queue for * @param queue - The event queue to add * @returns Promise that resolves when the queue is added * @throws {QueueExistsError} If a queue already exists for the task * * @example * ```typescript * const queue = new EventQueue(); * try { * await queueManager.add('task-123', queue); * console.log('Queue added successfully'); * } catch (error) { * if (error instanceof QueueExistsError) { * console.error('Queue already exists for this task'); * } * } * ``` */ add(taskId, queue) { return __awaiter(this, void 0, void 0, function* () { if (this.queues.has(taskId)) { throw new queue_manager_1.QueueExistsError(taskId); } this.queues.set(taskId, queue); this.initStats(taskId); }); } /** * Gets an existing queue for a task * * This method retrieves the event queue for a specific task. * It returns undefined if no queue exists for the task. * * @param taskId - ID of the task to get the queue for * @returns Promise resolving to the event queue, or undefined if not found * * @example * ```typescript * const queue = await queueManager.get('task-123'); * if (queue) { * console.log('Found queue for task'); * // Use the queue * } else { * console.log('No queue found for task'); * } * ``` */ get(taskId) { return __awaiter(this, void 0, void 0, function* () { return this.queues.get(taskId); }); } /** * Creates a new queue or gets an existing one * * This method retrieves the event queue for a specific task if it exists, * or creates a new one if it doesn't. It's a convenience method that * combines the functionality of add and get. * * @param taskId - ID of the task to get or create a queue for * @returns Promise resolving to the existing or newly created event queue * * @example * ```typescript * // Get or create a queue for a task * const queue = await queueManager.createOrGet('task-123'); * * // Use the queue * queue.subscribe(event => { * console.log(`Received event: ${event.type}`); * }); * ``` */ createOrGet(taskId) { return __awaiter(this, void 0, void 0, function* () { let queue = this.queues.get(taskId); if (!queue) { queue = new event_queue_1.EventQueue(); this.queues.set(taskId, queue); this.initStats(taskId); } return queue; }); } /** * Taps into an existing queue to create a new consumer * * This method creates a new event queue that receives copies of all events * published to the original queue for a specific task. It's useful for * creating specialized event handlers or for filtering events. * * @param taskId - ID of the task to tap the queue for * @returns Promise resolving to a new event queue that receives copies of events * @throws {NoQueueError} If no queue exists for the task * * @example * ```typescript * try { * // Create a specialized queue for completed tasks * const tapQueue = await queueManager.tap('task-123'); * * // Subscribe to events on the tapped queue * tapQueue.subscribe(event => { * if (event.type === 'taskCompleted') { * // Handle completed tasks * console.log('Task completed:', event.task.id); * } * }); * } catch (error) { * if (error instanceof NoQueueError) { * console.error('No queue exists for this task'); * } * } * ``` */ tap(taskId) { return __awaiter(this, void 0, void 0, function* () { const queue = this.queues.get(taskId); if (!queue) { throw new queue_manager_1.NoQueueError(taskId); } return queue.tap(); }); } /** * Closes and removes a queue * * This method shuts down the event queue for a specific task and removes * it from the manager. After calling this method, the queue will no longer * receive or publish events. * * @param taskId - ID of the task to close the queue for * @returns Promise that resolves when the queue is closed and removed * * @example * ```typescript * // When done with a task's queue * await queueManager.close('task-123'); * console.log('Queue closed and removed'); * ``` */ close(taskId) { const queue = this.queues.get(taskId); if (queue) { queue.close(); this.queues.delete(taskId); this.stats.delete(taskId); } return Promise.resolve(); } /** * Gets statistics for a queue * * This method retrieves statistics about the event queue for a specific task, * such as the number of events, consumers, and performance metrics. * * @param taskId - ID of the task to get queue statistics for * @returns Promise resolving to queue statistics * @throws {NoQueueError} If no queue exists for the task * * @example * ```typescript * try { * const stats = await queueManager.getStats('task-123'); * console.log('Queue size:', stats.size); * console.log('Number of consumers:', stats.consumers); * console.log('Events processed:', stats.processed); * } catch (error) { * if (error instanceof NoQueueError) { * console.error('No queue exists for this task'); * } * } * ``` */ getStats(taskId) { return __awaiter(this, void 0, void 0, function* () { const stats = this.stats.get(taskId); if (!stats) { throw new queue_manager_1.NoQueueError(taskId); } return stats; }); } /** * Initializes statistics for a new queue * * This private method creates a new statistics object for a queue * with default values for all metrics. * * @param taskId - ID of the task to initialize statistics for */ initStats(taskId) { this.stats.set(taskId, { size: 0, consumers: 0, processed: 0, failed: 0, lastActivity: new Date(), throughput: 0, avgProcessingTime: 0, errorRate: 0 }); } /** * Updates statistics for a queue * * This method updates the statistics for a specific task's queue with * the provided partial updates. It also updates the lastActivity timestamp. * * @param taskId - ID of the task to update statistics for * @param updates - Partial updates to apply to the statistics * @returns Promise that resolves when the statistics are updated * * @example * ```typescript * // Update the processed count and throughput * await queueManager.updateStats('task-123', { * processed: 10, * throughput: 2.5 * }); * ``` */ updateStats(taskId, updates) { return __awaiter(this, void 0, void 0, function* () { const stats = this.stats.get(taskId); if (stats) { Object.assign(stats, updates); stats.lastActivity = new Date(); } }); } } exports.InMemoryQueueManager = InMemoryQueueManager; //# sourceMappingURL=in-memory-queue-manager.js.map