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 returning a Promise in onRejected then() #168

Merged
merged 5 commits into from
Feb 21, 2022

Conversation

ezimuel
Copy link
Contributor

@ezimuel ezimuel commented Feb 16, 2022

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
License MIT

What's in this PR?

This PR allows to return a Promise in the onRejected callable function for HttpRejectedPromise. Right now is only possible to return a ResponseInterface for the $onRejected($this->exception) call, see here.

Why?

I'm proposing this change because I'm trying to implement a retry mechanism for async requests (related to this issue php-http/client-common#112). I did a POC in elastic-transport-php library that is using HTTPlug. See 8.x branch for the details.

Example Usage

Using this change we can easily implements a retry mechanism as follows:

use Http\Discovery\HttpAsyncClientDiscovery;
use Http\Discovery\Psr17FactoryDiscovery;

$client = HttpAsyncClientDiscovery::find();
$requestFactory = Psr17FactoryDiscovery::findRequestFactory();
$retries = 2; // number of HTTP retries
$request = $requestFactory->createRequest("GET", "http://localhost:8080/test");

// onFulfilled callable
$onFulfilled = function (ResponseInterface $response) {
    return $response;
};
// onRejected callable
$onRejected = function (Exception $e) use ($client, $request) {
    // $request can be different, e.g. using a Round-Robin algorithm

    // try another execution
    return $client->sendAsyncRequest($request);
};
$promise = $client->sendAsyncRequest($request);
for ($i=0; $i < $retries; $i++) {
    $promise = $promise->then($onFulfilled, $onRejected);
}
// Add the last callable to manage the exceeded maximum number of retries
$promise->then($onFulfilled, function(\Exception $e) {
    throw new \Exception(sprintf(
        "Exceeded maximum number of retries (%d): %s",
        $retries,
        $e->getMessage()
    ));
});

To Do

  • I'm not sure if a documentation pull request is needed

Copy link
Contributor

@dbu dbu left a comment

Choose a reason for hiding this comment

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

thank you for picking up the topic and creating this pull request. this looks good to me.

regarding documentation, i think it would make sense to add an explanation to https://docs.php-http.org/en/latest/components/promise.html

please also add a note to the CHANGELOG.md

and can you please rebase on master? i fixed the CI configuration so that all checks are green again.

@ezimuel ezimuel force-pushed the use-promise-as-return-on-rejected branch from 836e19f to f878059 Compare February 17, 2022 09:19
@ezimuel
Copy link
Contributor Author

ezimuel commented Feb 17, 2022

@dbu I updated the CHANGELOG and I sent this PR php-http/documentation#295 for the documentation. Thanks!

@ezimuel
Copy link
Contributor Author

ezimuel commented Feb 17, 2022

@dbu I forgot to mention, I used the 2.3.0 version in the CHANGELOG and I marked the date as 2022-02-x.

@ezimuel
Copy link
Contributor Author

ezimuel commented Feb 21, 2022

@dbu anything missing on this PR? Let me know if I can help, thanks.

CHANGELOG.md Outdated Show resolved Hide resolved
@dbu dbu merged commit 16e8b6f into php-http:master Feb 21, 2022
@dbu
Copy link
Contributor

dbu commented Feb 21, 2022

thanks a lot! here you go: https://github.com/php-http/httplug/releases/tag/2.3.0

@ezimuel
Copy link
Contributor Author

ezimuel commented Feb 21, 2022

Thanks @dbu for the quick release!

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.

None yet

3 participants