tourze/workerman-process-worker

Workerman 进程管理器,支持外部进程的监控和事件处理

Installs: 299

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/tourze/workerman-process-worker

0.1.0 2025-04-27 04:31 UTC

This package is auto-updated.

Last update: 2025-10-31 07:58:05 UTC


README

English | 中文

Latest Version Build Status Quality Score Code Coverage Total Downloads License

A Workerman extension that allows you to run and monitor external processes within the Workerman environment. This package provides seamless integration with external commands while maintaining the event-driven architecture of Workerman.

Inspired by https://github.com/workbunny

Table of Contents

Features

  • Process Management: Run any external command as a Workerman process
  • Real-time Monitoring: Monitor process output in real-time with event-driven architecture
  • Event System: Built-in Symfony EventDispatcher for flexible event handling
  • Lifecycle Management: Handle process start, output, and exit events
  • Custom Handlers: Support for custom process handlers via ProcessHandlerInterface
  • Seamless Integration: Easy integration with existing Workerman applications
  • Reload Support: Full support for Workerman's reload functionality
  • Dual Event API: Both callback and event listener approaches supported

Requirements

  • PHP 8.1 or higher
  • Workerman 5.1 or higher
  • Symfony EventDispatcher 7.3 or higher

Installation

Install the package via Composer:

composer require tourze/workerman-process-worker

Quick Start

Basic Usage

<?php

use Tourze\Workerman\ProcessWorker\ProcessWorker;
use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// Create a ProcessWorker with a command to run
$processWorker = new ProcessWorker('ping -c 3 google.com');

// Handle process output
$processWorker->onProcessOutput = function ($worker, $output) {
    echo "Process output: $output";
};

// Handle process exit
$processWorker->onProcessExit = function ($worker) {
    echo "Process has exited\n";
};

// Start Workerman
Worker::runAll();

Using Event Listeners (Recommended)

<?php

use Tourze\Workerman\ProcessWorker\ProcessWorker;
use Tourze\Workerman\ProcessWorker\Event\ProcessStartEvent;
use Tourze\Workerman\ProcessWorker\Event\ProcessOutputEvent;
use Tourze\Workerman\ProcessWorker\Event\ProcessExitEvent;
use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

$processWorker = new ProcessWorker('tail -f /var/log/syslog');

// Add event listeners
$processWorker->addListener(ProcessStartEvent::NAME, function (ProcessStartEvent $event) {
    echo "Process started: " . $event->getWorker()->getRunCommand() . "\n";
});

$processWorker->addListener(ProcessOutputEvent::NAME, function (ProcessOutputEvent $event) {
    echo "Output: " . $event->getOutput();
});

$processWorker->addListener(ProcessExitEvent::NAME, function (ProcessExitEvent $event) {
    echo "Process exited\n";
});

Worker::runAll();

Detailed Usage

Constructor Parameters

The ProcessWorker constructor accepts the following parameters:

public function __construct(
    string $runCommand,
    ?ProcessHandlerInterface $processHandler = null,
    ?EventDispatcherInterface $eventDispatcher = null
)
  • $runCommand: The command to execute
  • $processHandler: Optional custom process handler (defaults to DefaultProcessHandler)
  • $eventDispatcher: Optional custom event dispatcher (defaults to new EventDispatcher)

Event Types

The package provides three main events:

  1. ProcessStartEvent: Triggered when the process starts
  2. ProcessOutputEvent: Triggered when the process outputs data
  3. ProcessExitEvent: Triggered when the process terminates

Event Handling Methods

1. Callback Properties (Legacy)

$processWorker->onProcessStart = function ($worker) {
    echo "Process started\n";
};

$processWorker->onProcessOutput = function ($worker, $output) {
    echo "Output: $output";
};

$processWorker->onProcessExit = function ($worker) {
    echo "Process exited\n";
};

2. Event Listeners (Recommended)

use Tourze\Workerman\ProcessWorker\Event\ProcessStartEvent;
use Tourze\Workerman\ProcessWorker\Event\ProcessOutputEvent;
use Tourze\Workerman\ProcessWorker\Event\ProcessExitEvent;

// Add multiple listeners with different priorities
$processWorker->addListener(ProcessOutputEvent::NAME, function (ProcessOutputEvent $event) {
    file_put_contents('process.log', $event->getOutput(), FILE_APPEND);
}, 100); // High priority

$processWorker->addListener(ProcessOutputEvent::NAME, function (ProcessOutputEvent $event) {
    echo "Output: " . $event->getOutput();
}, 0); // Default priority

Custom Process Handler

You can implement your own process handler by implementing the ProcessHandlerInterface:

use Tourze\Workerman\ProcessWorker\Contract\ProcessHandlerInterface;

class MyProcessHandler implements ProcessHandlerInterface
{
    public function __construct(private string $command) {}
    
    public function start(): mixed
    {
        // Custom process starting logic
        return popen($this->command, 'r');
    }
    
    public function stop(mixed $process): void
    {
        // Custom cleanup logic
        if (is_resource($process)) {
            fclose($process);
        }
    }
    
    public function isRunning(mixed $process): bool
    {
        // Custom running check
        return is_resource($process) && !feof($process);
    }
    
    public function getCommand(): string
    {
        return $this->command;
    }
}

// Use custom handler
$processWorker = new ProcessWorker('my_command', new MyProcessHandler('my_command'));

Worker Configuration

Since ProcessWorker extends Workerman's Worker class, you can configure it like any other Worker:

$processWorker->count = 1; // Number of processes to start
$processWorker->name = 'MyProcessWorker'; // Name for the worker
$processWorker->reloadable = true; // Enable reload support (default: true)

Advanced Example

<?php

use Tourze\Workerman\ProcessWorker\ProcessWorker;
use Tourze\Workerman\ProcessWorker\Event\ProcessStartEvent;
use Tourze\Workerman\ProcessWorker\Event\ProcessOutputEvent;
use Tourze\Workerman\ProcessWorker\Event\ProcessExitEvent;
use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// Create a ProcessWorker for monitoring system logs
$logMonitor = new ProcessWorker('tail -f /var/log/nginx/access.log');
$logMonitor->name = 'LogMonitor';

// Log process start
$logMonitor->addListener(ProcessStartEvent::NAME, function (ProcessStartEvent $event) {
    echo "[" . date('Y-m-d H:i:s') . "] Log monitoring started\n";
});

// Process log entries
$logMonitor->addListener(ProcessOutputEvent::NAME, function (ProcessOutputEvent $event) {
    $line = trim($event->getOutput());
    if (empty($line)) {
        return;
    }
    
    // Parse log line and handle according to your needs
    if (strpos($line, 'ERROR') !== false) {
        // Handle error logs
        echo "[ERROR] $line\n";
    } else {
        // Handle regular logs
        echo "[INFO] $line\n";
    }
});

// Handle process exit
$logMonitor->addListener(ProcessExitEvent::NAME, function (ProcessExitEvent $event) {
    echo "[" . date('Y-m-d H:i:s') . "] Log monitoring stopped\n";
});

Worker::runAll();

API Reference

ProcessWorker Class

Constructor

public function __construct(
    string $runCommand,
    ?ProcessHandlerInterface $processHandler = null,
    ?EventDispatcherInterface $eventDispatcher = null
)

Properties

  • $onProcessStart: Callback for process start event
  • $onProcessOutput: Callback for process output event
  • $onProcessExit: Callback for process exit event

Methods

  • getProcessHandler(): ProcessHandlerInterface - Get the process handler
  • getEventDispatcher(): EventDispatcherInterface - Get the event dispatcher
  • addListener(string $eventName, callable $listener, int $priority = 0): void - Add event listener
  • getRunCommand(): string - Get the command being executed

Events

ProcessStartEvent

  • Event Name: process.start
  • Methods: getWorker(): ProcessWorker

ProcessOutputEvent

  • Event Name: process.output
  • Methods: getWorker(): ProcessWorker, getOutput(): string

ProcessExitEvent

  • Event Name: process.exit
  • Methods: getWorker(): ProcessWorker

ProcessHandlerInterface

Required methods for custom process handlers:

public function start(): mixed;              // Start the process
public function stop(mixed $process): void; // Stop the process
public function isRunning(mixed $process): bool; // Check if running
public function getCommand(): string;       // Get the command

Use Cases

  • Log Monitoring: Monitor application or system logs in real-time
  • Background Tasks: Run background processes with output monitoring
  • System Commands: Execute system commands with event-based handling
  • Process Orchestration: Coordinate multiple external processes
  • Data Processing: Stream data processing with external tools

Contributing

We welcome contributions! Please feel free to submit pull requests or create issues to improve this package.

Development Setup

  1. Clone the repository
  2. Install dependencies: composer install
  3. Run tests: ./vendor/bin/phpunit
  4. Run static analysis: ./vendor/bin/phpstan analyse

License

The MIT License (MIT). Please see License File for more information.