Skip to content

nexphant/runtime ​

Core persistent runtime engine. Manages workers, fiber event loop, connection pools, adaptive pressure control, and graceful shutdown.

Install ​

bash
composer require nexphant/runtime

What's Included ​

  • Worker — persistent worker process with exponential error backoff
  • FiberEventLoop — cooperative concurrency scheduler using PHP Fibers
  • ConnectionPool — fiber-aware connection pooling with waiter queue
  • AdaptiveRuntime — pressure-aware accept rate controller
  • SharedWorkerTable — cross-process worker stats via shared memory

Worker ​

Each worker runs a persistent event loop, accepting connections and dispatching requests.

php
use Nexphant\Runtime\Worker;

$worker = new Worker($server, $loop, options: [
    'max_backoff' => 60,  // max error backoff in seconds
]);

$worker->run();

On consecutive errors, the worker applies exponential backoff (2^n seconds, capped at max_backoff). The backoff resets when a request completes successfully.

FiberEventLoop ​

The event loop schedules fibers cooperatively. Sleeping fibers are managed with a priority heap for O(log n) wake-up scheduling.

php
use Nexphant\Runtime\FiberEventLoop;

$loop = new FiberEventLoop();

// Sleep a fiber for N milliseconds
$loop->sleepFiber($fiber, milliseconds: 250);

// Run the event loop
$loop->run();

Timers and sleeping fibers are drained in wake-time order, minimizing unnecessary iterations.

ConnectionPool ​

Fiber-aware pool. Callers that cannot immediately acquire a connection are queued and resumed when one is released.

php
use Nexphant\Runtime\ConnectionPool;

// Register a pool factory
ConnectionPool::register('db', function () {
    return new PDO('sqlite:storage/app.db');
}, size: 10);

// Acquire — suspends the current fiber if pool is exhausted
$conn = ConnectionPool::acquire('db');

// Release back to pool (resumes next waiter automatically)
ConnectionPool::release('db', $conn);

No busy-wait. Waiters are served FIFO when a connection is released.

AdaptiveRuntime ​

Monitors system pressure and adjusts the accept rate per tick to prevent overload.

php
use Nexphant\Runtime\Adaptive\AdaptiveRuntime;

$runtime = new AdaptiveRuntime($stats);

// Get current pressure score (0.0 – 1.0)
$pressure = $runtime->pressure();

// Get recommended accept limit for this tick
$limit = $runtime->acceptLimit();

Pressure is calculated once per tick and cached — subsequent calls within the same tick read the cached value.

SharedWorkerTable ​

Reads all worker stats from shared memory in a single bulk read with one lock acquire, minimising contention.

php
use Nexphant\Runtime\Adaptive\SharedWorkerTable;

$table = new SharedWorkerTable($shmKey, $workerCount);

// Write stats for this worker
$table->write($workerId, $stats);

// Read all worker stats — single lock, bulk read
$allStats = $table->readAll();

Runtime Options ​

OptionDefaultDescription
workers4Number of worker processes
max_backoff60Max error backoff in seconds per worker
event_loopautoEvent loop backend (auto, ev, event, native)
socket_drivernativeSocket backend (native, uv)
max_accept_per_tick32Max connections accepted per event loop tick
keep_alive_timeout30HTTP keep-alive timeout in seconds

Released under the MIT License.