Skip to main content
Glama
fast-cycle-orchestrator.js3.72 kB
/** * Fast Cycle Orchestrator * * Experimental sub-500ms heartbeat cycles for rapid orchestration. * Implements AIMD (Additive Increase/Multiplicative Decrease) backoff. * * EXPERIMENTAL - DO NOT USE IN PRODUCTION * * @see src/core/signal.js for production SignalBus */ const EventEmitter = require('events'); // Import from core Signal protocol const { Signal, SignalBus } = require('../../../src/core/signal'); class FastCycleOrchestrator extends EventEmitter { constructor(options = {}) { super(); this.config = { // Target cycle time (ms) targetCycleMs: options.targetCycleMs || 500, // Minimum cycle time (safety limit) minCycleMs: options.minCycleMs || 100, // Maximum cycle time (degraded mode) maxCycleMs: options.maxCycleMs || 5000, // AIMD parameters aimd: { additiveIncrease: options.additiveIncrease || 50, // ms to add on success multiplicativeDecrease: options.multiplicativeDecrease || 0.5 // factor on failure } }; this.state = { currentCycleMs: this.config.targetCycleMs, cycleCount: 0, successCount: 0, failureCount: 0, lastCycleTime: null, running: false }; this.cycleTimer = null; } /** * Start the orchestration loop */ start() { if (this.state.running) return; this.state.running = true; this.emit('start', { config: this.config }); this._scheduleCycle(); } /** * Stop the orchestration loop */ stop() { this.state.running = false; if (this.cycleTimer) { clearTimeout(this.cycleTimer); this.cycleTimer = null; } this.emit('stop', { state: this.state }); } /** * Schedule next cycle */ _scheduleCycle() { if (!this.state.running) return; this.cycleTimer = setTimeout(() => { this._executeCycle(); }, this.state.currentCycleMs); } /** * Execute a single cycle */ async _executeCycle() { const startTime = Date.now(); this.state.cycleCount++; try { // Emit cycle event for handlers to process await this._runCycleHandlers(); // Success - AIMD additive increase this.state.successCount++; this.state.currentCycleMs = Math.max( this.config.minCycleMs, this.state.currentCycleMs - this.config.aimd.additiveIncrease ); this.emit('cycle-complete', { cycleNumber: this.state.cycleCount, durationMs: Date.now() - startTime, nextCycleMs: this.state.currentCycleMs }); } catch (error) { // Failure - AIMD multiplicative decrease this.state.failureCount++; this.state.currentCycleMs = Math.min( this.config.maxCycleMs, Math.ceil(this.state.currentCycleMs / this.config.aimd.multiplicativeDecrease) ); this.emit('cycle-error', { cycleNumber: this.state.cycleCount, error: error.message, nextCycleMs: this.state.currentCycleMs }); } this.state.lastCycleTime = Date.now(); this._scheduleCycle(); } /** * Run cycle handlers (override in subclass) */ async _runCycleHandlers() { // Base implementation - emit event for external handlers const handlers = this.listeners('cycle'); for (const handler of handlers) { await handler(); } } /** * Get current metrics */ getMetrics() { return { cycleCount: this.state.cycleCount, successRate: this.state.cycleCount > 0 ? (this.state.successCount / this.state.cycleCount).toFixed(3) : 0, currentCycleMs: this.state.currentCycleMs, running: this.state.running }; } } module.exports = { FastCycleOrchestrator };

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/wheattoast11/openrouter-deep-research-mcp'

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