nexus-worker-pool
Core worker pool abstractions for distributing actors across parallel threads — pure PHP, no Swoole dependency.
What's in this package
WorkerNode— per-thread coordinator;spawn(Props, name)routes via hash ring,actorFor(path)resolves registered actorsWorkerActorRef<T>—ActorRef<T>for actors on a different worker;tell()delivers viaWorkerTransport,ask()returns aFuture<R>ConsistentHashRing— CRC32 ring with 150 virtual nodes; maps actor names to worker IDs deterministicallyWorkerPoolConfig—withThreads(int),withSystemNamePrefix(string)WorkerTransportinterface —send(int $targetWorker, Envelope): void/listen(callable): void; implementations:InMemoryWorkerTransport(tests),ThreadQueueTransport(Swoole)WorkerDirectoryinterface —register(path, workerId)/lookup(path)/has(path); implementations:InMemoryWorkerDirectory(tests),ThreadMapDirectory(Swoole)WorkerStartHandlerinterface — implement to set up actors when a worker thread starts
Install
composer require nexus-actors/worker-pool
Quick example
src/Worker/AppWorkerHandler.php
use Monadial\Nexus\WorkerPool\WorkerNode;
use Monadial\Nexus\WorkerPool\WorkerStartHandler;
use Monadial\Nexus\Core\Actor\Behavior;
use Monadial\Nexus\Core\Actor\Props;
final class AppWorkerHandler implements WorkerStartHandler
{
public function onWorkerStart(WorkerNode $node): void
{
$node->spawn(
Props::fromBehavior(Behavior::receive(
static fn($ctx, $msg): Behavior => Behavior::same(),
)),
'orders',
);
}
}
spawn() consults the hash ring: if the actor name hashes to this worker's ID it is spawned locally and returns a LocalActorRef; otherwise it registers the path with the owning worker and returns a WorkerActorRef that routes via transport.
See also
- nexus-worker-pool-swoole —
ThreadQueueTransport,ThreadMapDirectory, and theWorkerPoolDSL - Scaling / overview — topology guide