Download the PHP package yangusik/thrun without Composer
On this page you can find all versions of the php package yangusik/thrun. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download yangusik/thrun
More information about yangusik/thrun
Files in yangusik/thrun
Package thrun
Short Description Async queue worker engine for PHP with native threads + coroutines via TrueAsync.
License MIT
Informations about the package thrun
Thrun
Async queue worker for PHP built on TrueAsync — an alternative PHP core that implements true asynchrony by modifying the Zend engine, I/O libraries, database and socket handling.
Goal
The fastest async queue worker for PHP — one worker process that handles both IO-bound and CPU-bound tasks efficiently. Uses real OS threads instead of forked processes, consumes significantly less memory, and aims to outperform Symfony Messenger and Laravel Horizon.
Benchmarks
Measured on WSL2, 8GB RAM, PHP 8.6 TrueAsync fork:
| Scenario | IO throughput | CPU throughput | Stable RSS |
|---|---|---|---|
| Horizon 1 worker | 18/s | 73/s | 72 MB |
| Horizon 12 workers | 210/s | 514/s | 949 MB |
| TrueAsync 1x100 | 1,869/s | 452/s | 44 MB |
| TrueAsync 12x10 | 2,355/s | 2,059/s | 54 MB |
TrueAsync 12x10 uses 17x less RSS than Horizon 12 workers, 11x more IO throughput.
Requirements
- TrueAsync PHP 8.6+ (
trueasync/php-true-asyncDocker image) - ext-pcntl (for signal handling)
- ext-redis (Edmond's TrueAsync-compatible fork for Redis transport)
Installation
Package is in development and may change name.
Quick Start
Features
N OS Threads × M Coroutines
Each Worker spawns N real OS threads. Each thread runs a TaskGroup of M coroutines. Total concurrency is N × M. ThreadChannel provides backpressure and blocks when all coroutines are busy.
Per-Message Timeout (Hard Cancel)
Attach a TimeoutStamp to any message. If the handler exceeds the limit, it receives a hard cancellation that interrupts blocking operations like sleep, file_get_contents, or DB queries. finally blocks still execute.
Retry with Delay
Two stamps work together:
RetryStamp— defines the retry policy (backoff intervals and max attempts).RedeliveryStamp— added automatically by the worker on every redelivery. Keeps history of attempts and timestamps.
Alternatively, the handler can trigger a retry explicitly via Acknowledger without pre-attaching a stamp (see examples/retry_without_stamp.php).
Metrics
Inject a MetricsInterface to track throughput, failures, retries, timeouts, and average processing time.
Multi-Queue and Scheduling
One Worker can serve multiple queues simultaneously with pluggable scheduling:
RoundRobinStrategy— equal distribution across queuesPriorityStrategy— weighted credits, proportional distribution
Dispatch Policies
Limit concurrency per partition (tenant, user, etc.) via PartitionStamp:
Graceful Shutdown
Supervisor handles SIGINT/SIGTERM gracefully. Worker::stop() cancels the scope and closes internal resources. The producer unblocks from receive(). Pending jobs complete or timeout.
Explicit Acknowledgement
Handlers can accept an Acknowledger for explicit control:
Methods: $ack->ack(), $ack->retry(int $delayMs), $ack->fail(?Throwable).
Middleware
Wrap message processing in reusable middleware:
Stamps
Messages carry stamps for cross-cutting concerns:
| Stamp | Purpose |
|---|---|
DelayStamp |
Defer message delivery |
ErrorDetailsStamp |
Captures exception info on failure |
MessageIdStamp |
Unique message identifier |
PartitionStamp |
Partition key for dispatch policies |
QueueStamp |
Queue name (set by MultiQueueReceiver) |
RedeliveryStamp |
History of redelivery attempts |
RetryStamp |
Retry policy configuration |
TimeoutStamp |
Hard timeout for handler execution |
Redis Transport
At-least-once delivery via LMOVE from ready to processing. Delayed messages use a sorted set (ZADD). Reclaims the processing list on startup for crash recovery.
Uses a custom TrueAsync-compatible fork of
phpredis(early stage). Connection pooling must be enabled:
Failure Transport (Dead Letter)
Exhausted retries can be sent to a separate transport for inspection:
Failed messages carry an ErrorDetailsStamp with the exception class, message, code, and trace.
Examples
Run examples directly if you have TrueAsync PHP installed, or via Docker (see below).
one_queue.php — basic single-queue worker
Sends six emails to one queue and processes them sequentially.
two_queue.php — two queues with priority
Emails and notifications share one worker. Priority strategy favors emails (weight 3) over notifications (weight 1).
round_robin.php — round-robin scheduling
Emails and notifications alternate evenly.
priority.php — three queues with credits
Emails (3), ping (2), and notifications (1) compete. Higher-priority queues get more slots.
max_concurrency.php — per-partition limits
Max 2 concurrent jobs per partition. With 2 threads, the worker processes two messages in parallel, then waits for completion before taking the next batch.
retry.php — retry with backoff
Messages retry on failure with configurable delays. RetryStamp sets the policy; RedeliveryStamp tracks each attempt.
retry_without_stamp.php — explicit retry via Acknowledger
Handler decides to retry on its own; no RetryStamp is attached upfront.
middleware.php — error logging middleware
CatchMessageMiddleware prints every exception with message class and location before retry logic kicks in.
metrics.php — live metrics reporter
Real-time console output of processed / failed / retried / timed out counts plus average processing time.
redis.php — Redis-backed transport
Pushes 20 CPU-bound jobs to Redis, then processes them across 12 threads with live progress reporting.
Testing
Tests use testo. No mocking of TrueAsync internals — tests run with InMemoryTransport and real async execution.
Some transport tests require Redis running on localhost:6379.
Docker
If you want to test this project in Docker, here is an example setup.
Dockerfile:
docker-compose.yml:
License
MIT