Files
shopify-ai-backup/OPENCODE_PROCESS_MANAGER.md

9.9 KiB
Raw Blame History

OpenCode Process Manager

Overview

This document explains the OpenCode Process Manager implementation, which optimizes resource usage by managing OpenCode sessions through a singleton instance manager.

Problem Statement

Previously, the application spawned a new OpenCode process for every message sent by users. This meant:

  • Multiple concurrent sessions resulted in dozens of separate OpenCode processes
  • High memory and CPU overhead from process spawning
  • No process reuse or pooling
  • Inefficient resource utilization

Solution

The OpencodeProcessManager class provides a singleton manager that:

  1. Tracks all OpenCode sessions in a centralized location
  2. Monitors process execution with detailed logging
  3. Prepares for future optimization when OpenCode supports server/daemon mode
  4. Falls back gracefully to per-message spawning when server mode is unavailable

Current Implementation

Architecture

┌─────────────────────────────────────┐
│   Multiple User Sessions            │
│  (Session A, B, C, D...)            │
└───────────┬─────────────────────────┘
            │
            ▼
┌─────────────────────────────────────┐
│  OpencodeProcessManager (Singleton) │
│  - Tracks all sessions              │
│  - Monitors execution               │
│  - Manages process lifecycle        │
└───────────┬─────────────────────────┘
            │
            ▼
┌─────────────────────────────────────┐
│  OpenCode CLI Execution             │
│  (Currently: per-message processes) │
│  (Future: single daemon instance)   │
└─────────────────────────────────────┘

Key Features

  1. Singleton Pattern: Only one OpencodeProcessManager instance exists across the entire application
  2. Session Tracking: Maps session IDs to their workspace directories
  3. Process Monitoring: Logs execution time, active processes, and resource usage
  4. Graceful Degradation: Falls back to per-message spawning if server mode unavailable
  5. Lifecycle Management: Properly initialized on startup and cleaned up on shutdown

Code Locations

  • Manager Class: Lines ~575-836 in server.js
  • Singleton Instance: Line ~838 in server.js
  • Integration: Line ~6165 in server.js (sendToOpencode function)
  • Initialization: Lines ~11239-11246 in server.js (bootstrap function)
  • Shutdown: Line ~981 in server.js (gracefulShutdown function)
  • Status Endpoint: Lines ~9832-9867 in server.js

Current Behavior

What Happens Now

Since OpenCode doesn't currently support a persistent server/daemon mode, the manager:

  1. Tracks each execution with detailed logging
  2. Reports statistics via the /api/opencode/status endpoint
  3. Routes through executeStandalone which spawns per-message processes
  4. Logs process lifecycle (start, duration, completion)

This provides:

  • Better visibility into OpenCode usage
  • Centralized execution management
  • Foundation for future optimization
  • ⚠️ Still spawns separate processes per message (but tracked)

Future Optimization

When OpenCode Adds Server Mode

If/when OpenCode supports a persistent server/daemon mode (e.g., opencode serve or opencode daemon):

  1. Update getServerModeArgs() to return the correct command arguments
  2. The manager will automatically:
    • Start a single OpenCode process on server startup
    • Route all sessions through this single instance
    • Maintain persistent connections
    • Dramatically reduce resource overhead

Expected Benefits (Future)

When server mode is available:

  • 90%+ reduction in process spawning overhead
  • Faster response times (no process startup delay)
  • Lower memory usage (one process vs. many)
  • Better session continuity (persistent state)

Monitoring

Status Endpoint

Check OpenCode manager status:

curl http://localhost:3000/api/opencode/status

Response includes:

{
  "available": true,
  "version": "...",
  "runningProcesses": 3,
  "activeStreams": 2,
  "processManager": {
    "isRunning": false,
    "isReady": true,
    "pendingRequests": 0,
    "activeSessions": 5,
    "lastActivity": 1234567890,
    "idleTime": 1234,
    "mode": "per-session",
    "description": "Each message spawns separate OpenCode process"
  }
}

Logging

The manager logs:

  • Process execution start/end
  • Duration of each command
  • Active process count
  • Session workspace mapping
  • Errors and failures

Look for log entries with:

  • "OpenCode process manager..."
  • "Executing OpenCode command (standalone)"
  • "OpenCode command completed"

Implementation Details

OpencodeProcessManager Class

Properties

  • process: Reference to the persistent OpenCode process (when in server mode)
  • isReady: Boolean indicating if the manager is ready to accept requests
  • pendingRequests: Map of in-flight requests awaiting responses
  • sessionWorkspaces: Map of session IDs to their workspace directories
  • lastActivity: Timestamp of last activity (for idle detection)
  • heartbeatInterval: Timer for keeping persistent connection alive

Methods

start()

  • Initializes the manager
  • Attempts to start OpenCode in server mode
  • Falls back to per-session mode if unavailable

executeInSession(sessionId, workspaceDir, command, args, options)

  • Main execution method
  • Routes through persistent process (future) or standalone spawning (current)
  • Tracks session -> workspace mapping

executeStandalone(workspaceDir, command, args, options)

  • Current fallback implementation
  • Spawns individual OpenCode process
  • Logs execution metrics

stop()

  • Gracefully shuts down manager
  • Terminates persistent process if running
  • Cleans up resources

getStats()

  • Returns current manager statistics
  • Used by monitoring endpoint

Integration Points

  1. Bootstrap (startup): Manager initialized after all state is loaded
  2. sendToOpencode: Routes all OpenCode executions through manager
  3. gracefulShutdown: Stops manager before server shutdown
  4. Status endpoint: Exposes manager statistics

Testing

Verify Installation

  1. Start the server:

    node chat/server.js
    
  2. Check the logs for:

    Initializing OpenCode process manager...
    OpenCode does not support server mode, will use per-session approach
    OpenCode process manager initialized
    
  3. Check status endpoint:

    curl http://localhost:3000/api/opencode/status | jq .
    
  4. Send a message in a session and observe logs:

    Executing OpenCode command (standalone) { processId: '...', activeProcesses: 1 }
    OpenCode command completed { processId: '...', duration: 1234 }
    

Multiple Concurrent Sessions

  1. Open multiple builder sessions in different browser tabs
  2. Send messages in each
  3. Check /api/opencode/status to see runningProcesses count
  4. Each process should be logged with start/end times

Configuration

No configuration required. The manager automatically:

  • Detects if OpenCode supports server mode
  • Falls back to per-session spawning
  • Adapts to available capabilities

Performance Impact

Current (Per-Session Mode)

  • Better tracking and visibility
  • Centralized management
  • Foundation for future optimization
  • No performance improvement yet (still spawns separate processes)

Future (Server Mode)

  • 90%+ reduction in process overhead
  • Faster response times
  • Lower memory usage
  • Better resource utilization

Migration Notes

This change is backward compatible:

  • No changes to session management
  • No changes to API endpoints (except enhanced status response)
  • No changes to client behavior
  • Existing sessions continue to work

Troubleshooting

Manager Not Starting

Check logs for: "OpenCode process manager initialization failed"

  • This is expected if OpenCode doesn't support server mode
  • Manager falls back to per-session spawning automatically

Multiple Processes Still Running

This is expected behavior in current mode:

  • Each message spawns a separate process
  • This will change when OpenCode adds server mode support
  • All processes are now tracked and logged

Status Endpoint Not Responding

  1. Verify server is running
  2. Check that route is registered in routeInternal()
  3. Look for initialization errors in logs

Future Enhancements

  1. Add Server Mode Support: Update getServerModeArgs() when available
  2. Request Batching: Queue and batch multiple requests
  3. Connection Pooling: Maintain pool of persistent connections
  4. Load Balancing: Distribute across multiple OpenCode instances
  5. Health Checks: Monitor and restart unresponsive instances

Summary

The OpenCode Process Manager provides:

  • Centralized session management
  • Comprehensive execution tracking
  • Foundation for future optimization
  • Graceful fallback to current behavior
  • Enhanced monitoring and debugging

While currently operating in per-session mode, it's ready to leverage OpenCode's server mode as soon as it becomes available, providing significant resource savings and performance improvements.