composer require asyncbase/asyncbase
ASYNCBASE_KEY=sk_live_...
Plain PHP
<?php
require 'vendor/autoload.php';
use AsyncBase\Queue;
$q = new Queue(getenv('ASYNCBASE_KEY'));
$r = $q->send('emails', ['to' => 'a@b.com'], delay: '30s');
foreach ($q->pull('emails', group: 'workers', limit: 10, waitSeconds: 5) as $msg) {
try {
handle($msg->payload);
$msg->ack();
} catch (\Throwable $e) {
$msg->nack();
}
}
Laravel service provider
app/Providers/AppServiceProvider.php
use AsyncBase\Queue;
public function register(): void
{
$this->app->singleton(Queue::class, fn () =>
new Queue(env('ASYNCBASE_KEY'))
);
}
Controller
use AsyncBase\Queue;
class EmailController extends Controller
{
public function __construct(private readonly Queue $queue) {}
public function send(Request $req): JsonResponse
{
$r = $this->queue->send('emails', $req->validated(), delay: '30s');
return response()->json(['id' => $r->id]);
}
}
Artisan consumer
app/Console/Commands/ConsumeEmails.php
use AsyncBase\Queue;
use Illuminate\Console\Command;
class ConsumeEmails extends Command
{
protected $signature = 'asyncbase:consume';
public function handle(Queue $q): int
{
foreach ($q->consume('emails', group: 'laravel-workers', visibilitySeconds: 60) as $msg) {
try { handle($msg->payload); $msg->ack(); }
catch (\Throwable $e) { $msg->nack(); }
}
return self::SUCCESS;
}
}
Run under supervisor:
[program:asyncbase-consume]
command=php /var/www/html/artisan asyncbase:consume
autostart=true
autorestart=true
user=www-data
Error handling
PHP’s built-in Exception uses $code for an integer, so the error code is
on $errorCode.
use AsyncBase\AsyncBaseError;
try {
$q->send('emails', [...]);
} catch (AsyncBaseError $e) {
if ($e->errorCode === 'RATE_LIMITED') {
sleep(1);
} else {
throw $e;
}
}