Skip to main content
Glama
throttled-sender.ts2.48 kB
export interface ThrottledSenderOptions { debounceMs?: number; maxWaitMs?: number; } /** * A throttled sender that delays and deduplicates messages by key. * - Each message is delayed by debounceMs (default 1000ms) * - If multiple messages with the same key arrive during the delay, only the latest is sent * - To prevent starvation, messages are guaranteed to send within maxWaitMs of the first attempt */ export class ThrottledSender { private readonly pendingMessages = new Map< string, { payload: unknown; debounceTimeout: NodeJS.Timeout; maxTimeout: NodeJS.Timeout; } >(); private readonly debounceMs: number; private readonly maxWaitMs: number; constructor( private readonly sender: ( key: string, payload: unknown, correlationId?: string, ) => void, options: ThrottledSenderOptions = {}, ) { this.debounceMs = options.debounceMs ?? 1000; this.maxWaitMs = options.maxWaitMs ?? 1000; } sendNow(key: string, payload: unknown, correlationId?: string): void { this.sender(key, payload, correlationId); } send(key: string, payload: unknown): void { const existing = this.pendingMessages.get(key); if (existing) { // Update the payload to the latest existing.payload = payload; // Clear and reset the debounce timer clearTimeout(existing.debounceTimeout); existing.debounceTimeout = setTimeout(() => { this.flush(key); }, this.debounceMs); // Keep the existing max timeout as is } else { // First message for this key - set up both timers const debounceTimeout = setTimeout(() => { this.flush(key); }, this.debounceMs); const maxTimeout = setTimeout(() => { this.flush(key); }, this.maxWaitMs); this.pendingMessages.set(key, { payload, debounceTimeout, maxTimeout, }); } } shutdown(): void { // Flush all pending messages for (const key of Array.from(this.pendingMessages.keys())) { this.flush(key); } this.pendingMessages.clear(); } private flush(key: string): void { const pending = this.pendingMessages.get(key); if (!pending) return; // Clear both timeouts clearTimeout(pending.debounceTimeout); clearTimeout(pending.maxTimeout); // Remove from pending this.pendingMessages.delete(key); // Send the message this.sender(key, pending.payload); } }

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/TheLunarCompany/lunar'

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