-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Symptoms, their causes, and the fix. All examples assume
use InitPHP\FiberLoops\Loop;.
Cause. You called next() or sleep() (with a positive duration) outside a
fiber — usually from the main script rather than from inside a task.
Fix. Move the call into a task passed to defer() or await():
$loop = new Loop();
// ✗ Wrong — main context:
// $loop->next();
// ✓ Right — inside a task:
$loop->defer(function () use ($loop) {
$loop->next();
echo "ok\n";
});
$loop->run();See Error Handling.
Cause. The same root cause as above, but reaching PHP's native error — for
example calling Fiber::suspend() yourself outside a fiber. Inside FiberLoops,
next()/sleep() wrap this as a LoopException; if you see the raw FiberError,
something is suspending a fiber directly.
Fix. Suspend only through next()/sleep(), and only inside a task.
Cause. The first task never yields, so cooperative scheduling lets it run to completion before any sibling advances.
Fix. Add next() at the points where it is fair to hand over control:
$loop = new Loop();
$loop->defer(function () use ($loop) {
foreach (range(1, 3) as $n) {
echo "a$n\n";
$loop->next(); // <-- without this, a1 a2 a3 print before any b
}
});
$loop->defer(function () use ($loop) {
foreach (range(1, 3) as $n) {
echo "b$n\n";
$loop->next();
}
});
$loop->run();See Core Concepts → Cooperative, not preemptive.
Cause. A task never terminates. run() only ends when the queue drains, so an
infinite task with no exit condition blocks forever.
Fix. Give long-lived tasks an exit condition and return from them. See
Recipes → Graceful shutdown.
Cause. Busy-waiting — most often, tasks spending their time in sleep(), which
spins rather than idling. With nothing else to do, the loop re-checks the clock as
fast as it can.
Fix. This is expected for a pure scheduler. If you need efficient idle waiting
on timers or I/O, FiberLoops alone is not the right tool — use a full async runtime
(ReactPHP, Amp) or build a reactor on
top. See Caveats → sleep() is a busy-wait.
Cause. An uncaught exception inside a task propagates out of run(), and tasks
queued after it on that pass do not run.
Fix. Catch inside the task to isolate the failure:
$loop = new Loop();
$loop->defer(function () {
try {
riskyWork();
} catch (\Throwable $e) {
// log and move on — the loop keeps running
}
});
$loop->run();See Error Handling → Exceptions thrown inside a task.
Cause. Resuming or awaiting a fiber that is currently running — for example
awaiting the task's own fiber, or sharing one Fiber object between two awaiters.
Fix. await() other tasks, not the currently executing one, and do not hand
the same Fiber instance to two places. See
Caveats → Do not await() the running fiber.
Cause. FiberLoops requires PHP 8.1+ (fibers do not exist before 8.1).
Fix. Upgrade PHP to 8.1 or later, then composer require initphp/fiber-loops.
Check your version with php -v.
- Open an issue with a minimal reproducer (a short standalone script).
- Ask in the org-wide Discussions.
Getting Started
Using FiberLoops
Guides
Reference