Skip to main content
Glama
mutex.ts1.35 kB
/** * A simple per-key async mutex to serialize operations targeting the same resource (e.g., a tmux pane). * * Usage: * const mutex = new KeyMutex(); * await mutex.runExclusive(windowId, async () => { * // perform tmux send-keys + capture-pane safely for this window * }); */ export class KeyMutex { private tails = new Map<string, Promise<void>>(); /** * Run the provided async function exclusively for the given key. * Calls for the same key will execute sequentially in FIFO order. */ async runExclusive<T>(key: string, fn: () => Promise<T>): Promise<T> { const prev = this.tails.get(key) ?? Promise.resolve(); let resolveNext: () => void; const next = new Promise<void>((res) => { resolveNext = res; }); // Chain next after prev and store as new tail this.tails.set( key, prev.then(() => next) ); // Wait for prior tasks for this key to finish await prev; try { return await fn(); } finally { // Release this task resolveNext!(); // Best-effort cleanup: if no further tasks were queued, remove the tail // (Not strictly necessary, but keeps the map small in steady state) Promise.resolve().then(() => { if (this.tails.get(key) === next) { this.tails.delete(key); } }); } } }

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/NightTrek/Terminally-mcp'

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