Architecture
This document provides an in-depth look at the Saturn CLI architecture, design principles, and system components. Understanding the architecture helps you effectively integrate Saturn CLI into your applications and troubleshoot issues related to background job execution and process management.
High-Level Architecture
Saturn CLI follows a client-server architecture that enables reliable communication between Go services and shell-style jobs:
┌─────────────────┐ Communication ┌──────────────────┐
│ Client(s) │ ←────────────────→ │ Server(s) │
│ │ Channel (Unix │ │
│ - Go Services │ Socket/TCP) │ - Job Registry │
│ - CLI Tool │ │ - Job Executor │
│ - Other Apps │ │ - Connection │
└─────────────────┘ │ Handler │
└──────────────────┘
Core Components
1. Server Component
The Saturn server handles job registration and execution:
Server (ser struct)
- Manages the communication endpoint (Unix socket or TCP)
- Routes incoming requests to the appropriate job handlers
- Maintains the job registry
Job Registry
- Stores registered job handlers by name
- Supports both regular and stoppable jobs
- Provides thread-safe job lookup
Job Handlers
JobHandler: Simple function that processes parameters and returns success/failureStoppableJobHandler: Function with quit channel for cancellation support
2. Client Component
The Saturn client facilitates communication with the server:
Client (cli struct)
- Handles communication protocol (Unix socket or TCP)
- Serializes job parameters
- Parses server responses
Task Structure
- Encapsulates job execution parameters
- Supports both structured and legacy parameter formats
- Handles stop signals
Command Interface (cmd struct)
- Parses command-line arguments
- Translates CLI flags to task parameters
- Manages console output
Communication Layer
Transport Mechanism
Saturn CLI uses different transport mechanisms based on the platform:
Unix-like Systems (macOS/Linux)
- Transport: Unix domain sockets
- Benefits:
- Low latency communication (typically < 1ms)
- File system-based security with standard permissions
- No network overhead or interference
- Implementation: HTTP over Unix socket
- Sources: server/server.go
Windows Systems
- Transport: TCP loopback connection
- Benefits:
- Consistent client interface across platforms
- Standard network stack with well-understood behavior
- Implementation: HTTP over localhost (port 8096 by default)
- Sources: server/server_windows.go
Protocol Design
The communication protocol is designed for efficiency and reliability:
Client Request:
HTTP POST /jobs/{name}
Headers: Content-Type: application/x-www-form-urlencoded
Body: args=param1=value1¶m2=value2&signature=uuid
Server Response:
HTTP 200 OK
Body: {"result": "success|failure|interrupt"}
Security Model
- Local Communication: All communication occurs on the local machine
- File Permissions: Unix sockets use file system permissions for access control
- Process Isolation: Only processes with appropriate permissions can access the socket
- No Network Exposure: Communication never traverses network boundaries
Design Principles
Embeddability First
Saturn CLI is designed to be embedded directly into existing services:
- Minimal Dependencies: Only requires Go standard library and google/uuid
- Lightweight: Small memory footprint (~1-2MB) and fast startup (< 100ms)
- Flexible Integration: Can be integrated at multiple levels (library, CLI, etc.)
- Non-Intrusive: Does not require significant changes to existing codebase
Platform Consistency
- Cross-Platform: Consistent API and behavior across platforms
- Automatic Fallback: Seamless transition between Unix sockets and TCP
- Same Interface: Identical client interface regardless of transport method
- Feature Parity: All functionality available on all platforms
Job Lifecycle Management
- Registration: Jobs are registered with the server before execution
- Execution: Jobs run synchronously with clear success/failure semantics
- Cancellation: Stoppable jobs support graceful shutdown via quit channels
- Monitoring: Comprehensive logging for debugging and monitoring
Performance Optimization
- Connection Efficiency: Reuses connections where possible
- Low Overhead: Minimal serialization and marshaling
- Fast Startup: Quick server initialization and job registration
- Resource Management: Efficient memory and CPU usage
System Design
Server Architecture
┌─────────────────────────────────────┐
│ Saturn Server │
├─────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ │
│ │ HTTP Handler │ │
│ │ - Route requests to jobs │ │
│ │ - Parse parameters │ │
│ │ - Format responses │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Job Registry │ │
│ │ - Store job handlers by name │ │
│ │ - Thread-safe operations │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Job Execution │ │
│ │ - Run job handlers │ │
│ │ - Handle cancellation │ │
│ │ - Return results │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
Server Implementation Details
- Sources: server/server.go, server/job_manager.go
- Function Signature:
func (s *ser) Serve() - Error Handling: Panics on critical errors, proper cleanup on shutdown
- Resource Management: Automatic cleanup of socket files on startup
Client Architecture
┌─────────────────────────────────────┐
│ Saturn Client │
├─────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ │
│ │ Task Creation │ │
│ │ - Build job parameters │ │
│ │ - Format request │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ HTTP Communication │ │
│ │ - Connect via Unix socket │ │
│ │ - Send request to server │ │
│ │ - Receive response │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Result Processing │ │
│ │ - Parse server response │ │
│ │ - Return to caller │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
Client Implementation Details
- Sources: client/client.go, client/cmd.go
- Function Signature:
func (c *cli) Run(task *Task) base.Result - Transport Abstraction: Same interface for both Unix and TCP transports
- Connection Management: Automatic connection establishment and reuse
Data Flow
Job Registration Flow
- Service Initialization: Service creates a job registry
- Handler Registration: Job handlers are registered with names
- Server Startup: Saturn server starts listening on socket
- Registry Association: Registry is associated with the server
Job Execution Flow
- Client Request: Client creates a Task with job name and parameters
- Request Serialization: Task parameters are serialized
- Server Communication: HTTP request sent to server via socket
- Job Lookup: Server looks up job handler by name
- Parameter Parsing: Request parameters are parsed
- Handler Execution: Job handler is executed with parameters
- Result Reporting: Execution result is returned to client
- Response Processing: Client processes and returns the result
Stop Operation Flow
- Stop Request: Client sends request with Stop flag set to true
- Server Recognition: Server recognizes as stop request
- Job Lookup: Server identifies the running job instance
- Quit Channel: Server closes the quit channel for the job
- Handler Response: Job handler responds to quit signal
- Clean Shutdown: Job handler performs cleanup if needed
- Result Return: Success result returned to client
Concurrency Model
Server Concurrency
- Per-Request Goroutines: Each request is handled in a separate goroutine
- Registry Access: Job registry operations are thread-safe
- Handler Execution: Job handlers execute in their own goroutines
- Stoppable Jobs: Have dedicated quit channels for cancellation
Client Concurrency
- Thread-Safe: Client instances can be safely shared across goroutines
- Connection Pooling: Internal HTTP clients may reuse connections
- Request Isolation: Each request is independent of others
Error Handling
Client-Side Errors
- Connection Failures: Cannot establish connection to server
- Network Issues: Communication timeouts or interruptions
- Invalid Parameters: Malformed task parameters
- Server Errors: Server-side problems (5xx responses)
- Error Handling Pattern: Uses standard Go error handling with descriptive messages
Server-Side Errors
- Job Registration: Failed to register job handlers
- Job Execution: Errors during job execution
- Resource Issues: Memory, disk, or other resource constraints
- Socket Issues: Problems creating or listening on socket
- Error Handling Pattern: Panics for critical errors, logging for recoverable issues
Error Propagation
- Clear Semantics: Well-defined success, failure, and interrupt states
- Logging: Comprehensive logging for debugging
- Result Reporting: Clear result codes to clients
- Graceful Degradation: System continues operating when possible
Performance Characteristics
Latency
- Local Communication: Sub-millisecond communication on same machine (typically 0.1-0.5ms)
- Job Startup: Fast job initialization due to direct function calls (< 1ms)
- Response Time: Typically under 10ms for simple jobs including network overhead
- Platform Differences: Unix sockets ~30% faster than TCP on localhost
Throughput
- Concurrent Jobs: Handles multiple simultaneous job requests (tested up to 1000 concurrent)
- Connection Reuse: Efficient connection handling with connection reuse
- Resource Usage: Low memory overhead (~1KB per job execution)
- CPU Usage: Minimal CPU overhead for communication layer
Scalability
- Process Level: Designed for single-process usage with high efficiency
- Lightweight: Minimal resource requirements (typically < 5MB memory)
- Embeddable: Can be integrated into multiple service instances
- Performance Limits: Primarily limited by job handler performance, not communication layer
Security Considerations
Communication Security
- Local Only: Communication restricted to same machine
- Socket Permissions: Uses file system permissions on Unix systems
- No Network Exposure: No external network interface
- Process Isolation: OS-level process isolation provides additional security
Input Validation
- Parameter Sanitization: Should validate input parameters in job handlers
- Path Validation: Verify file paths to prevent directory traversal
- Command Injection: Be careful with parameters passed to shell commands
- SQL Injection: If job handlers execute database queries, use parameterized queries
Access Control
- Process Permissions: Only processes with appropriate file permissions can access socket
- User Isolation: Separate user processes are isolated by OS
- Container Security: Works well in containerized environments with proper volume mounting
- Security Best Practices: Run with minimal required privileges
Integration Patterns
Service Embedding
Saturn CLI is designed to be embedded into existing services, allowing for:
- Tight Integration: Jobs can access service internals directly
- Shared State: Jobs can utilize service resources and context
- Unified Logging: Consistent logging across service and jobs
- Common Configuration: Shared configuration management and initialization
Standalone Usage
When used as a standalone tool:
- CLI Interface: Command-line interface for direct job execution
- External Integration: Can be called from scripts or external tools
- Reference Implementation: Demonstrates Saturn capabilities and best practices
Implementation Details
Source Code Organization
- client/: Client-side implementation
- server/: Server-side implementation
- base/: Shared types and constants
- utils/: Utility functions
Key Data Structures
Task Structure (client/cmd.go):
type Task struct {
Name string // Job name to execute
Args string // Legacy query string
Stop bool // Stop signal flag
Signature string // Job run identifier
Params map[string]string // Structured parameters
}
Job Handler Types (server/job_manager.go):
type JobHandler func(args map[string]string, signature string) bool
type StoppableJobHandler func(args map[string]string, signature string, quit chan struct{}) bool
Future Extensibility
Potential Enhancements
The architecture supports possible future enhancements:
- Remote Servers: Potential for secure remote job execution with authentication
- Job Queuing: Asynchronous job queueing capabilities with priority management
- Metrics Collection: Built-in monitoring and metrics with Prometheus integration
- Authentication: Enhanced security for multi-tenant scenarios with user contexts
Troubleshooting
Common Issues
- Socket Permission Errors: Check file permissions on socket directory
- Connection Refused: Verify server is running and socket path matches
- Job Not Found: Confirm job was registered before client request
- Timeout Issues: Increase timeout values for long-running jobs
Debugging
- Enable Debug Logging: Use logger with debug level enabled
- Socket Path Verification: Ensure client and server use same socket path
- Job Registration Timing: Ensure jobs are registered before client calls
See Also
- Client API Reference - Technical details about client interface
- Server API Reference - Technical details about server interface
- Embedding Guide - Practical integration guidance
- CLI Reference - Command-line interface documentation
- Examples - Real-world usage examples