liquidrazor/posix-runtime is a small PHP 8.3+ library that provides POSIX runtime primitives for isolated worker execution.
It is transport-agnostic process-control infrastructure for the LiquidRazor micro-kernel lifecycle. It does not implement HTTP, CLI, queue, gRPC, routing, DI, logging, scheduling, or daemon management.
- PHP
8.3+ ext-posixext-pcntl
Missing required extensions are treated as runtime failures. The library does not silently degrade to PID-only supervision.
Current public surface:
- immutable value objects under
include/Value - enums under
include/Enum - typed exceptions under
include/Exception - public contracts under
include/Contract - a thin public facade:
LiquidRazor\PosixRuntime\PosixRuntime
Current runtime behavior:
- worker identity generation
- worker process metadata before and after fork
- centralized POSIX/PCNTL adapter boundary
- raw wait-status interpretation
- signal handler registration
- pending-signal dispatch
- child execution wrapping
- parent-side worker supervision
- graceful shutdown requests
- forced termination escalation
This library does not implement:
- transport kernels
- framework bootstrapping
- event manager infrastructure
- process event catalogs
- service containers
- schedulers
- external process-manager replacement behavior
Higher-level kernels are expected to plug into the runtime lifecycle exposed here.
The main entry point is LiquidRazor\PosixRuntime\PosixRuntime.
It currently exposes:
capabilityStatus(): RuntimeCapabilityStatusassertAvailable(): voidrun(WorkerExecutionRequest $request): SupervisionResultshutdown(WorkerProcessMetadata $metadata, ShutdownRequest $request): SupervisionResult
Typical value types involved in public calls:
WorkerIdWorkerIdentityProcessIdWorkerProcessMetadataWorkerExecutionRequestWorkerExecutionResultWorkerExitStatusShutdownRequestSupervisionResult
<?php
declare(strict_types=1);
use LiquidRazor\PosixRuntime\Include\Value\ProcessId;
use LiquidRazor\PosixRuntime\Include\Value\WorkerExecutionRequest;
use LiquidRazor\PosixRuntime\Include\Value\WorkerId;
use LiquidRazor\PosixRuntime\Include\Value\WorkerIdentity;
use LiquidRazor\PosixRuntime\Include\Value\WorkerProcessMetadata;
use LiquidRazor\PosixRuntime\PosixRuntime;
$runtime = new PosixRuntime();
$request = new WorkerExecutionRequest(
WorkerProcessMetadata::prepare(
new WorkerIdentity(new WorkerId('example-worker'), 'example-worker'),
new ProcessId(posix_getpid()),
),
static fn (): int => 0,
);
$result = $runtime->run($request);SupervisionResult contains:
- the final
WorkerExecutionResult - an optional
ShutdownRequest - a
forcedTerminationflag
The implemented lifecycle is:
Parent prepares worker metadata
Parent forks worker
Parent path:
receive child PID
supervise with waitpid()
dispatch pending signals
interpret final status
return structured result
Child path:
install child-local signal handlers
execute callback
exit with explicit code
The runtime currently models these worker states:
PreparedSpawnedRunningFinishedCrashedShutdownRequestedTerminatedForcedTermination
Termination reasons are modeled separately:
CompletedNonZeroExitSignalShutdownRequestedForcedTerminationCrash
The runtime currently supports explicit registration and dispatch of:
SIGTERMSIGINTSIGQUITwhen supported by the platformSIGCHLD
Signal behavior is explicit:
- handlers are registered through dedicated services
- pending signals are dispatched deliberately
- child-local termination handlers re-signal with the default handler so parent supervision sees signal termination correctly
Parent-side supervision is driven by waitpid() through the adapter layer.
Implemented outcomes include:
- successful completion
- non-zero exit
- signal termination
- shutdown-requested completion
- forced termination
Shutdown coordination currently supports:
- send graceful signal
- wait until timeout
- escalate to forced signal when required
The library uses typed exceptions for meaningful runtime failures, including:
MissingPosixExtensionMissingPcntlExtensionRuntimeUnavailableForkFailedSignalRegistrationFailedInvalidWorkerStateTransitionWorkerExecutionFailedWorkerCrashedWorkerTerminatedBySignalWaitOperationFailedShutdownTimeoutExceededForcedTerminationFailed
Structured results are used for normal process outcomes. Exceptions are reserved for unavailable runtime capabilities or failed control operations.
include/
Contract/
Enum/
Exception/
Value/
lib/
Runtime/
Signal/
Supervision/
src/
PosixRuntime.php
tests/
Dependency direction is strict:
include <- lib <- src
The current PHPUnit suite covers:
- value-model invariants
- capability detection
- adapter failure mapping
- exit-status interpretation
- signal registration and dispatch
- spawn and child execution
- parent-side supervision
- graceful shutdown
- forced termination escalation
- public facade wiring
Process tests skip cleanly when POSIX support is unavailable and include defensive child cleanup to avoid zombie processes.
MIT