# Process Package Specification ## Overview The Process package provides a robust system process handling system that matches Laravel's process functionality. It supports process execution, input/output handling, process pools, and signal handling while integrating with our Event and Queue packages. > **Related Documentation** > - See [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md) for implementation status > - See [Foundation Integration Guide](foundation_integration_guide.md) for integration patterns > - See [Testing Guide](testing_guide.md) for testing approaches > - See [Getting Started Guide](getting_started.md) for development setup > - See [Events Package Specification](events_package_specification.md) for process events > - See [Queue Package Specification](queue_package_specification.md) for background processing ## Core Features ### 1. Process Manager ```dart /// Core process manager implementation class ProcessManager implements ProcessContract { /// Container instance final Container _container; /// Active processes final Map _processes = {}; /// Process event dispatcher final EventDispatcherContract _events; ProcessManager(this._container, this._events); /// Starts a process Future start( String command, [ List? arguments, ProcessOptions? options ]) async { options ??= ProcessOptions(); var process = await Process.start( command, arguments ?? [], workingDirectory: options.workingDirectory, environment: options.environment, includeParentEnvironment: options.includeParentEnvironment, runInShell: options.runInShell ); _processes[process.pid] = process; await _events.dispatch(ProcessStarted(process)); return process; } /// Runs a process to completion Future run( String command, [ List? arguments, ProcessOptions? options ]) async { var process = await start(command, arguments, options); var result = await process.exitCode; await _events.dispatch(ProcessCompleted( process, result )); return ProcessResult( process.pid, result, await _readOutput(process.stdout), await _readOutput(process.stderr) ); } /// Kills a process Future kill(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) async { var process = _processes[pid]; if (process == null) return; process.kill(signal); await _events.dispatch(ProcessKilled(process)); _processes.remove(pid); } /// Gets active processes List get activeProcesses => List.from(_processes.values); /// Reads process output Future _readOutput(Stream> stream) async { var buffer = StringBuffer(); await for (var data in stream) { buffer.write(String.fromCharCodes(data)); } return buffer.toString(); } } ``` ### 2. Process Pool ```dart /// Process pool for parallel execution class ProcessPool { /// Maximum concurrent processes final int concurrency; /// Process manager final ProcessManager _manager; /// Active processes final Set _active = {}; /// Pending commands final Queue _pending = Queue(); ProcessPool(this._manager, {this.concurrency = 5}); /// Starts a process in the pool Future start( String command, [ List? arguments, ProcessOptions? options ]) async { var pending = PendingCommand( command, arguments, options ); _pending.add(pending); await _processQueue(); return await pending.future; } /// Processes pending commands Future _processQueue() async { while (_active.length < concurrency && _pending.isNotEmpty) { var command = _pending.removeFirst(); await _startProcess(command); } } /// Starts a process Future _startProcess(PendingCommand command) async { var process = await _manager.start( command.command, command.arguments, command.options ); _active.add(process); process.exitCode.then((result) { _active.remove(process); command.complete(ProcessResult( process.pid, result, '', '' )); _processQueue(); }); } } ``` ### 3. Process Events ```dart /// Process started event class ProcessStarted { /// The started process final Process process; ProcessStarted(this.process); } /// Process completed event class ProcessCompleted { /// The completed process final Process process; /// Exit code final int exitCode; ProcessCompleted(this.process, this.exitCode); } /// Process killed event class ProcessKilled { /// The killed process final Process process; ProcessKilled(this.process); } /// Process failed event class ProcessFailed { /// The failed process final Process process; /// Error details final Object error; ProcessFailed(this.process, this.error); } ``` ### 4. Process Options ```dart /// Process execution options class ProcessOptions { /// Working directory final String? workingDirectory; /// Environment variables final Map? environment; /// Include parent environment final bool includeParentEnvironment; /// Run in shell final bool runInShell; /// Process timeout final Duration? timeout; /// Idle timeout final Duration? idleTimeout; /// Retry attempts final int retryAttempts; /// Retry delay final Duration retryDelay; ProcessOptions({ this.workingDirectory, this.environment, this.includeParentEnvironment = true, this.runInShell = false, this.timeout, this.idleTimeout, this.retryAttempts = 0, this.retryDelay = const Duration(seconds: 1) }); } ``` ## Integration Examples ### 1. Basic Process Execution ```dart // Run process var result = await processManager.run('ls', ['-la']); print('Output: ${result.stdout}'); print('Exit code: ${result.exitCode}'); // Start long-running process var process = await processManager.start('server', ['--port=8080']); await process.exitCode; // Wait for completion ``` ### 2. Process Pool ```dart // Create process pool var pool = ProcessPool(processManager, concurrency: 3); // Run multiple processes await Future.wait([ pool.start('task1'), pool.start('task2'), pool.start('task3'), pool.start('task4') // Queued until slot available ]); ``` ### 3. Process Events ```dart // Listen for process events events.listen((event) { print('Process ${event.process.pid} started'); }); events.listen((event) { print('Process ${event.process.pid} completed with code ${event.exitCode}'); }); // Start process await processManager.start('long-task'); ``` ## Testing ```dart void main() { group('Process Manager', () { test('runs processes', () async { var manager = ProcessManager(container, events); var result = await manager.run('echo', ['Hello']); expect(result.exitCode, equals(0)); expect(result.stdout, contains('Hello')); }); test('handles process failure', () async { var manager = ProcessManager(container, events); expect( () => manager.run('invalid-command'), throwsA(isA()) ); }); }); group('Process Pool', () { test('limits concurrent processes', () async { var pool = ProcessPool(manager, concurrency: 2); var started = []; events.listen((event) { started.add(event.process.pid.toString()); }); await Future.wait([ pool.start('task1'), pool.start('task2'), pool.start('task3') ]); expect(started.length, equals(3)); expect(started.take(2).length, equals(2)); }); }); } ``` ## Next Steps 1. Implement core process features 2. Add process pool 3. Add process events 4. Add retry handling 5. Write tests 6. Add benchmarks ## Development Guidelines ### 1. Getting Started Before implementing process features: 1. Review [Getting Started Guide](getting_started.md) 2. Check [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md) 3. Follow [Testing Guide](testing_guide.md) 4. Use [Foundation Integration Guide](foundation_integration_guide.md) 5. Review [Events Package Specification](events_package_specification.md) 6. Review [Queue Package Specification](queue_package_specification.md) ### 2. Implementation Process For each process feature: 1. Write tests following [Testing Guide](testing_guide.md) 2. Implement following Laravel patterns 3. Document following [Getting Started Guide](getting_started.md#documentation) 4. Integrate following [Foundation Integration Guide](foundation_integration_guide.md) ### 3. Quality Requirements All implementations must: 1. Pass all tests (see [Testing Guide](testing_guide.md)) 2. Meet Laravel compatibility requirements 3. Follow integration patterns (see [Foundation Integration Guide](foundation_integration_guide.md)) 4. Support event integration (see [Events Package Specification](events_package_specification.md)) 5. Support queue integration (see [Queue Package Specification](queue_package_specification.md)) ### 4. Integration Considerations When implementing process features: 1. Follow patterns in [Foundation Integration Guide](foundation_integration_guide.md) 2. Ensure Laravel compatibility per [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md) 3. Use testing approaches from [Testing Guide](testing_guide.md) 4. Follow development setup in [Getting Started Guide](getting_started.md) ### 5. Performance Guidelines Process system must: 1. Handle concurrent processes efficiently 2. Manage system resources 3. Support process pooling 4. Scale with process count 5. Meet performance targets in [Laravel Compatibility Roadmap](laravel_compatibility_roadmap.md#performance-benchmarks) ### 6. Testing Requirements Process tests must: 1. Cover all process operations 2. Test concurrent execution 3. Verify event handling 4. Check resource cleanup 5. Follow patterns in [Testing Guide](testing_guide.md) ### 7. Documentation Requirements Process documentation must: 1. Explain process patterns 2. Show pool examples 3. Cover error handling 4. Include performance tips 5. Follow standards in [Getting Started Guide](getting_started.md#documentation)