Im playing around with defer in laravel. I have this:
Route::get('testing', function () {
defer(function(){
// sleep(3);
Log::info('sleeping');
})
->always(); // Will always run defer once executed
return 'Rtoufasdfa';
});
Im getting this in my sail terminal.
PHP Fatal error: Uncaught SwooleError: API must be called in the coroutine in /var/www/html/routes/web.php:94
Stack trace:
2024-11-08 23:15:05,688 INFO reaped unknown pid 1093 (exit status 255)
2024-11-08 23:15:05,688 INFO reaped unknown pid 1094 (exit status 255)
#0 /var/www/html/routes/web.php(94): defer()
anyone familiar with defer whove ran into this issue?
2
Answers
This means it looks like defer() requires a coroutine context, not available in standard Laravel routes.
If one needs to run some tasks at the end of a request,
try using register_shutdown_function since this function works outside coroutines:
The error SwooleError: API must be called in the coroutine indicates that the defer function is being called outside of a Swoole coroutine context. Swoole’s defer function is designed to run cleanup tasks at the end of a coroutine, so it needs to be called within a coroutine.
In Laravel, if you’re using Sail with Swoole, your code execution might not always be in a coroutine by default, especially in route closures. To solve this issue, you can make sure your code runs inside a coroutine.
Here’s how you can wrap your code inside a coroutine for testing purposes:
If you need a more permanent solution for using coroutines within a controller or other parts of the application, you may want to use a Swoole-compatible package, such as swooletw/laravel-swoole, which can handle coroutine context automatically. Then, define your logic within a controller, ensuring it’s compatible with Swoole’s coroutine system.
With this approach, the code in defer will execute correctly inside a coroutine, and the always() call should work as expected.
Let me know if this helps resolve your error!