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

Allow an empty EachPromise to be resolved by running the queue #178

Merged
merged 5 commits into from
Mar 27, 2025

Conversation

madelson
Copy link
Contributor

@madelson madelson commented Mar 7, 2025

Closes #176.

@@ -80,9 +80,9 @@ public function promise(): PromiseInterface
}

try {
$this->iterable->rewind();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flipped the ordering here so that createPromise() can check whether the iterable is empty.

// In the case of empty, create a promise that will immediately become resolved via wait() or
// via Utils::queue()->run() (https://github.com/guzzle/promises/issues/176). We could simply
// create a fulfilled promise here, but that would be an observable behavioral change (see
// EachPromiseTest::testResolvesInCaseOfAnEmptyListAndInvokesFulfilled)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if you agree with the approach taken here vs. changing testResolvesInCaseOfAnEmptyListAndInvokesFulfilled to call Utils::queue()->run() before checking that fulfilled is called.

Originally I had thought it would make sense for an empty EachPromise to resolve synchronously without even needing to pump the queue.

However, this solution works just as well for me in terms of making EachPromise "fiber-friendly" and preserves the existing behavior more exactly.

@@ -430,4 +441,23 @@ public function testIsWaitableWhenLimited(): void
$this->assertSame(['a', 'c', 'b', 'd'], $called);
$this->assertTrue(P\Is::fulfilled($p));
}

public function testRewindsExhaustedIterator(): void
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just tests existing behavior that my first pass at the change broke; figured it was worth adding to document.

@madelson
Copy link
Contributor Author

@GrahamCampbell thoughts? Do you think this change could be accepted?

@madelson
Copy link
Contributor Author

@GrahamCampbell any next steps for this? Looks like all checks are now passing

@GrahamCampbell GrahamCampbell changed the base branch from 2.0 to 2.1 March 27, 2025 12:06
@GrahamCampbell GrahamCampbell changed the title Allow an empty EachPromise to be resolved by running the queue. Fix #176 Allow an empty EachPromise to be resolved by running the queue Mar 27, 2025
@GrahamCampbell
Copy link
Member

Thanks for working on this. I'm going to target this at 2.1.x, rather than 2.0.x.

@GrahamCampbell GrahamCampbell merged commit be70a65 into guzzle:2.1 Mar 27, 2025
13 checks passed
@GrahamCampbell
Copy link
Member

Ooops, this introduces a bug caught by an upstream test suite. Fix: #179.

@GrahamCampbell
Copy link
Member

Actually, I need to revert this. The promise resolving with null is a major issue.

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

Successfully merging this pull request may close these issues.

EachPromise should complete synchronously OR at least queue pumping its iterable upon creation
2 participants