Skip to main content
Glama
executor.ts2.79 kB
/** * Request Queue for Sequential Tool Execution * Ensures only one tool runs at a time to prevent resource conflicts */ export type QueuedTask<T> = () => Promise<T>; interface QueueItem<T> { task: QueuedTask<T>; resolve: (value: T) => void; reject: (error: Error) => void; } /** * Sequential execution queue that processes tasks one at a time */ export class RequestQueue { private queue: QueueItem<unknown>[] = []; private isProcessing = false; private currentTask: string | null = null; /** * Add a task to the queue and wait for its completion */ async enqueue<T>(task: QueuedTask<T>, _taskName?: string): Promise<T> { return new Promise((resolve, reject) => { this.queue.push({ task: task as QueuedTask<unknown>, resolve: resolve as (value: unknown) => void, reject, }); this.processQueue(); }); } /** * Process the queue one task at a time */ private async processQueue(): Promise<void> { if (this.isProcessing) { return; } this.isProcessing = true; while (this.queue.length > 0) { const item = this.queue.shift(); if (!item) break; try { const result = await item.task(); item.resolve(result); } catch (error) { item.reject(error instanceof Error ? error : new Error(String(error))); } } this.isProcessing = false; this.currentTask = null; } /** * Get the current queue length */ get length(): number { return this.queue.length; } /** * Check if the queue is currently processing */ get busy(): boolean { return this.isProcessing; } /** * Get the name of the currently executing task */ get current(): string | null { return this.currentTask; } /** * Clear all pending tasks from the queue */ clear(): void { const error = new Error('Queue cleared'); for (const item of this.queue) { item.reject(error); } this.queue = []; } } // Singleton instance for global tool execution queue let globalQueue: RequestQueue | null = null; /** * Get the global request queue instance */ export function getGlobalQueue(): RequestQueue { if (!globalQueue) { globalQueue = new RequestQueue(); } return globalQueue; } /** * Execute a tool through the global queue */ export async function executeQueued<T>( task: QueuedTask<T>, taskName?: string ): Promise<T> { return getGlobalQueue().enqueue(task, taskName); } /** * Decorator to queue a function's execution */ export function queued<T extends (...args: unknown[]) => Promise<unknown>>( target: T, taskName?: string ): T { return (async (...args: Parameters<T>) => { return executeQueued(() => target(...args), taskName); }) as T; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abd3lraouf/specter-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server