Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EachPromise should complete synchronously OR at least queue pumping its iterable upon creation #176

Open
mikethea1 opened this issue Jan 22, 2025 · 0 comments

Comments

@mikethea1
Copy link

PHP version: 8.2.12 (hint: php --version)

Description
If an EachPromise (or methods reliant of it like Each::of) is constructed with an empty iterable, it returns a promise in the pending state that only completes when waited on. In contrast, if the iterator has at least one item (even a fulfilled promise!) then it can be completed by running the queue.

It would be nice if things were more consistent. Either Each should always use the queue or it should complete synchronously if there is no async work to be done.

How to reproduce

// Empty case
$p = Each::of((function($b) { if ($b) { yield 1; } })(false));
$p->getState(); // "pending"
$p->then(function() { echo "DONE!"; });
\GuzzleHttp\Promise\Utils::queue()->run(); // does not print "DONE!"

// Non-empty case
$p = Each::of((function($b) { if ($b) { yield 1; } })(true));
$p->then(function() { echo "DONE!"; });
\GuzzleHttp\Promise\Utils::queue()->run(); // prints "DONE!"

Possible Solution
One solution would be to add the following code at the start of EachPromise::createPromise():

if (!$this->iterable->valid()) { return $this->aggregate = new FulfilledPromise(null); }

This way, it would complete synchronously with an empty iterator.

Additional context
The reason this is impacting me is that I'm using php fibers as a layer on top of Guzzle. When I want to wait on a promise, I need to pump the event loop (via CurlMultiHandler::tick()) to advance all promises until the current one is complete. This doesn't work if a promise becomes "orphaned" such that it is neither complete nor completable via the queue or the curl handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant