8000 Add support for exponential backoff on retry by nbraun-amazon · Pull Request #1986 · phpredis/phpredis · GitHub
[go: up one dir, main page]

Skip to content

Add support for exponential backoff on retry #1986

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
Jul 20, 2021

Conversation

nbraun-amazon
Copy link
Contributor

No description provided.

Copy link
Member
@michael-grunder michael-grunder left a comment

Choose a reason for hiding this comment

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

This looks quite good. Let me know what you think of the modifications.

Also, it may be worth prefixing any visible functions with redis_ given that C uses a global namespace. I didn't get any symbol conflicts when building the whole PHP 8 source tree but it's usually better to be safe about it.

Example of what I mean by renaming:

-struct Backoff {
+struct RedisBackoff {
     int       algorithm;        /* index of algorithm function, returns backoff in microseconds*/
     zend_long base;             /* base backoff in microseconds */
     zend_long cap;              /* max backoff in microseconds */
@@ -10,17 +10,17 @@ struct Backoff {
 };
 /* }}} */
 
-zend_long default_backoff(struct Backoff *self, int retry_index);
+zend_long redis_default_backoff(struct RedisBackoff *self, int retry_index);

/* etc... */

library.c Outdated
Comment on lines 343 to 347
if (redis_sock->retry_interval) {
// Random factor to avoid having several (or many) concurrent connections trying to reconnect at the same time
long retry_interval = (count ? redis_sock->retry_interval : (php_rand() % redis_sock->retry_interval));
zend_long retry_interval = backoff_compute(&redis_sock->backoff, retry_index);
usleep(retry_interval);
}
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can remove the if (retry_interval) { ... } and just compute the backoff with backoff_compute. Simpler to follow I think.

            /* Sleep based on our backoff algorithm */
            zend_long delay = backoff_compute(&redis_sock->backoff, retry_index);
            if (delay != 0)
                usleep(delay);

From my initial testing this works as expected (e.g. returns 0 if retry_interval is 0)

Choose a reason for hiding this comment

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

Agreed. Fixed.

backoff.c Outdated
return MIN(self->cap, backoff);
}

zend_long exponential_backoff(struct Backoff *self, int retry_index) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need exponential backoff if it is always worse than jitter backoff? Is there any use cases why users may choose it?

Copy link
Member

Choose a reason for hiding this comment

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

I'm honestly not sure. Maybe we could reorder the array of options to put the best overall algorithms first?

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe we could remove useless algorithms? 😄

Copy link
Member

Choose a reason for hiding this comment

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

I think you make a good point.

@nbraun-amazon thoughts?

Choose a reason for hiding this comment

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

I'd say leave the current option first, then reorder. I did it in this new revision.

Copy link
Member
@michael-grunder michael-grunder Jul 18, 2021

Choose a reason for hiding this comment

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

@yatsukhnenko I don't mind leaving them in (as non-defaults and at the end of the list). I can see a use for testing since the non-jitter algorithms are deterministic.

@natbraun
Copy link

Hey @michael-grunder, thanks for your feedback :)

I submitted a new version. I prefixed with either redis_ or Redis where it made sense. I also reordered the algorithms, and switched to unsigned arithmetic to avoid nasty things on overflow.

@natbraun
Copy link

Once we agree, I'll also update the documentation. Thanks!

redis_commands.c Outdated
case REDIS_OPT_BACKOFF_ALGORITHM:
val_long = zval_get_long(val);
if(val_long >= 0 &&
val_long < BACKOFF_ALGORITHMS) {
Copy link
Member

Choose a reason for hiding this comment

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

This was changed to REDIS_BACKOFF_ALGORITHM

backoff.c Outdated

#include "backoff.h"

zend_ulong random_range(zend_ulong min, zend_ulong max) {
Copy link
Member

Choose a reason for hiding this comment

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

Might as well declare this static.

@michael-grunder
Copy link
Member

LGTM, if you make those two tiny changes I'll get this merged.

(I fat-fingered the "close pull request" on accident) 😄

@nbraun-amazon
Copy link
Contributor Author

hey @michael-grunder, I made the changes accordingly. Please note that the documentation has not been updated yet. Let's discuss it.

@yatsukhnenko
Copy link
Member

@nbraun-amazon could you also rebase your PR onto develop branch to run tests via GH Actions

@nbraun-amazon
Copy link
Contributor Author

@yatsukhnenko done

@nbraun-amazon
Copy link
Contributor Author

Build is failing because of missing ext/standard/php_mt_rand.h header. Looking into it.

@nbraun-amazon nbraun-amazon force-pushed the develop branch 6 times, most recently from 9a3d50c to 781e526 Compare July 19, 2021 19:11
@nbraun-amazon
Copy link
Contributor Author

@michael-grunder I pushed a new revision which should fix the 7.0 build. I guess you can approve the workflow so we can double-check it builds correctly. Thanks!

@michael-grunder
Copy link
Member

@yatsukhnenko If you're OK with this I'll get it merged tomorrow.

@natbraun
Copy link

All checks passed :)

@michael-grunder michael-grunder merged commit 7c7f2fa into phpredis:develop Jul 20, 2021
@michael-grunder
Copy link
Member

Merged, thanks!

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.

4 participants
0