Cookbook

Migrating to Async

Patterns and examples for moving from sequential I/O to concurrent execution.

This guide shows how to convert common sequential code into async with fibers, improving latency for I/O-bound work.

When to Migrate

  • Multiple independent I/O calls (HTTP, DB, file, network) per request
  • Long tail latencies from external services
  • Batch aggregation from multiple endpoints

Avoid for CPU-bound work; use queues or background jobs instead.

Enable per-route

$router->get('/dashboard', [DashboardController::class, 'show'])
    ->middleware(['async']);

Before → After: Parallel HTTP

Before (sequential):

use Glueful\Http\Response;

$a = $http->get('https://api.example.com/a');
$b = $http->get('https://api.example.com/b');
return Response::success(['a' => $a->json(), 'b' => $b->json()]);

After (concurrent):

use Glueful\Http\Response;

$ta = async(fn() => $http->get('https://api.example.com/a'));
$tb = async(fn() => $http->get('https://api.example.com/b'));
[$a, $b] = await_all([$ta, $tb]);
return Response::success(['a' => $a->json(), 'b' => $b->json()]);

Cancellation and Timeouts

$token = cancellation_token();
$task = async(fn() => $service->slowOp($token), $token);

// cancel on user action/timeout
$token->cancel();
try { await($task); } catch (\Throwable $e) { /* handle */ }

Per-call timeout:

use Glueful\Async\Contracts\Timeout;

$timeout = Timeout::fromSeconds(2.0);
$resp = await($http->sendAsync($request, $timeout));

Batching and Fan-out

$tasks = [];
foreach ($ids as $id) {
    $tasks[$id] = async(fn() => $svc->fetch($id));
}
$results = await_all($tasks);

Error Handling

Await will rethrow task exceptions. For partial failure handling:

$tasks = [
  'users' => async(fn() => $svc->users()),
  'posts' => async(fn() => $svc->posts()),
];

try {
  $out = await_all($tasks);
} catch (\Throwable $e) {
  // inspect individual tasks for granular handling if needed
  // or use Promise API if chaining is preferred
}

Tips

  • Keep async blocks small and well-scoped.
  • Respect cancellation tokens in loops and sleep/waits.
  • Ensure idempotency for retried operations.
  • Measure with metrics to validate improvements.