Can we check that current function/method is running in async()
function?
#546
Replies: 3 comments 12 replies
-
Hey @kodmanyagha, In short: No. But more interestingly what are the issues you are seeing? And what is behind that |
Beta Was this translation helpful? Give feedback.
-
Hey @kodmanyagha, interesting question 👍 I'm not sure if there should be the need to check this as we should be able to tell from looking at the function. First of all, using the Wrapping the Loop::addTimer(0.5, React\Async\async(function () {
echo 'a';
React\Async\await(React\Promise\Timer\sleep(1.0));
echo 'c';
}));
Loop::addTimer(1.0, function () {
echo 'b';
});
// prints "a" at t=0.5s
// prints "b" at t=1.0s
// prints "c" at t=1.5s Once we call the callback function of our first timer after 0.5 seconds, we print an "a" and then call the When using the In your example above you describe using just the I hope this helps a bit to understand how |
Beta Was this translation helpful? Give feedback.
-
Probably I found that how to detect the current function is called by async or not. I'm getting stack trace and looking the caller list, if closest caller is Now, this is function async(callable $function): callable
{
return static function (mixed ...$args) use ($function): PromiseInterface {
$fiber = null;
$promise = new Promise(function (callable $resolve, callable $reject) use ($function, $args, &$fiber): void {
$fiber = new \Fiber(function () use ($resolve, $reject, $function, $args, &$fiber): void {
try {
$resolve($function(...$args));
} catch (\Throwable $exception) {
$reject($exception);
} finally {
assert($fiber instanceof \Fiber);
FiberMap::unregister($fiber);
}
});
FiberMap::register($fiber);
$fiber->start();
... This is example usage of async(fn() => $this->fnMustCalledFromAsync())(); I think everybody can see the algorithm. Take a look to <?php
declare(strict_types=1);
namespace Tests\Feature;
use Exception;
use React\EventLoop\Loop;
use Tests\Base\DbInitializedTestCase;
use Throwable;
use function React\Async\async;
use function React\Async\await;
use function React\Promise\resolve;
use function React\Promise\Timer\sleep as rsleep;
class AsyncTest extends DbInitializedTestCase
{
public function test_async_detect()
{
$loop = Loop::get();
$loop->addTimer(0, function () {
async(fn() => $this->exampleFn(1))(); // This works well.
//$this->exampleFn(3); // This throws error.
});
$loop->run();
// Test purpose, doesn't mean anything.
$this->assertNotNull($loop);
}
/**
* This is my solution. We must put this top of the necessary function.
*
* @throws Exception
*/
protected function sureAsync(): void
{
$stackTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
//echo(json_encode($stackTrace, JSON_PRETTY_PRINT) . PHP_EOL . PHP_EOL);
if (count($stackTrace) <= 2) {
throw new Exception("You must call this function inside of a closure which called by async().");
}
$foundIndex = null;
foreach ($stackTrace as $index => $item) {
if ($index === 0) {
continue;
}
if ($item["function"] === 'React\Async\{closure}') {
$foundIndex = $index;
break;
}
}
if (is_null($foundIndex)) {
throw new Exception("You must call this function inside of a closure which called by async() in " . $stackTrace[1]["file"] . ':' . $stackTrace[1]["line"]);
}
}
/**
* @throws Throwable
*/
protected function exampleFn(int $no): void
{
// Now we can be sure with peace of mind that this function is called by `async()`.
$this->sureAsync();
logInfo($no . " function running.");
// Actually fibers aren't solving our problem. Because even though we are not in async,
// it brings the current fiber.
//$fiber = Fiber::getCurrent();
//if (is_null($fiber)) {
// logInfo($no . " fiber not found.");
//} else {
// logInfo($no . " fiber found, is running: " . (int)$fiber->isRunning());
//}
// If we're not in async context rsleep() is throwing error.
await(rsleep(1));
}
}
|
Beta Was this translation helpful? Give feedback.
-
Hi folks, I want to learn that how can I check that current method is running asynchronous or not. Example code here:
I didn't find any solution for this. If there is a way for doing this please write here. Thanks all.
Beta Was this translation helpful? Give feedback.
All reactions