Files
shopify-ai-backup/OPENCODE_PROCESS_MANAGER.md

292 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](chat/server.js)
- **Singleton Instance**: Line ~838 in [server.js](chat/server.js)
- **Integration**: Line ~6165 in [server.js](chat/server.js) (sendToOpencode function)
- **Initialization**: Lines ~11239-11246 in [server.js](chat/server.js) (bootstrap function)
- **Shutdown**: Line ~981 in [server.js](chat/server.js) (gracefulShutdown function)
- **Status Endpoint**: Lines ~9832-9867 in [server.js](chat/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:
```bash
curl http://localhost:3000/api/opencode/status
```
Response includes:
```json
{
"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:
```bash
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:
```bash
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.