Skip to content

Support maxlag and Retry-After header #28

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

Merged
merged 1 commit into from
Jan 23, 2017

Conversation

c960657
Copy link
Contributor

@c960657 c960657 commented Jan 22, 2017

When using the maxlag parameter, the API may an error code maxlag and a Retry-After HTTP header (documented here: https://www.mediawiki.org/wiki/Manual:Maxlag_parameter).

This patch adds maxlag to the list of error codes that should cause a retry, and it makes the API use the delay reported by the API.

It also mocks out the actual sleep() call so tests now run faster.

@c960657 c960657 changed the title Support Retry-After header Support maxlag and Retry-After header Jan 22, 2017
new Response( 503 ),
new Response( 200 ),
)
);
Copy link
Member

Choose a reason for hiding this comment

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

These test methods are quite long and I see this part repeated several times, perhaps some things can be factored out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

return function( $numberOfRetries ) {
return function( $numberOfRetries, Response $response = null ) {
// The $response argument is only passed as of Guzzle 6.2.2.
if( $response ) {
Copy link
Member

Choose a reason for hiding this comment

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

Small detail: I think explicit checks are typically better: $response !== null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

$retryAfter = $response->getHeaderLine( 'Retry-After' );
if( is_numeric( $retryAfter ) ) {
return 1000 * $retryAfter;
} elseif( $retryAfter ) {
Copy link
Member

Choose a reason for hiding this comment

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

You can almost always avoid if-else stuff. You can have two guard clauses here:

if (a) {
    return x;
}

if (b) {
    return y;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

strstr( $data['error']['info'], 'anti-abuse measure' )
)
) {
$shouldRetry = true;
Copy link
Member

Choose a reason for hiding this comment

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

This method is really long... though that was the case before already and you did not make it worse

$this->assertEquals( [ 1000 ] , $delays );
}

protected function getDelayMocker( &$delays )
Copy link
Member

Choose a reason for hiding this comment

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

why not private? also: bracket is misplaced

return function( $numberOfRetries, Response $response = null ) {
// The $response argument is only passed as of Guzzle 6.2.2.
if( $response !== null ) {
// Retry-After may be a number of seonds or an absolute date.
Copy link
Member

Choose a reason for hiding this comment

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

seonds -> seconds
It also might be nice to include a link to https://www.mediawiki.org/wiki/Manual:Maxlag_parameter here in a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have included a link in newRetryDecider().

}

if( $retryAfter ) {
$seconds = strtotime( $retryAfter ) - time();
Copy link
Member

Choose a reason for hiding this comment

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

Is there some documentation that states that the header may contain a date / timestamp rather than a value in seconds?
I can't see it on the wiki page and I imagine including code like this will lead to some odd wait times if a date is returned due to timezones.

Copy link
Contributor Author

@c960657 c960657 Jan 23, 2017

Choose a reason for hiding this comment

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

The API doc doesn't mention in, but it is allowed according to RFC 7231, section 7.1.3, so I thought it was worth spending a few lines on.

The RFC requires the absolute date returned to be a full date with timezone in a format supported by strtotime(), so timezones are not a problem. But it may cause issues if the local clock is very far behind – but I don't expect that to be a common problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added a reference to RFC 7231 in a comment.

Copy link
Member

Choose a reason for hiding this comment

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

Brilliant!

@addshore addshore merged commit 0563f0b into addwiki:master Jan 23, 2017
@addshore
Copy link
Member

Thanks for the PRs! :)

addwiki-ci pushed a commit that referenced this pull request Feb 2, 2021
* Start toward phpunit 9 WIP though...

* There are no integration tests in datamodel
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.

3 participants