Skip to content

Commit 52ad4bd

Browse files
committed
Use a random backoff factor for session store with faster retries
1 parent c85d902 commit 52ad4bd

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

php_memcached.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ PHP_INI_BEGIN()
370370
#ifdef HAVE_MEMCACHED_SESSION
371371
MEMC_SESSION_INI_BOOL ("locking", "1", OnUpdateBool, lock_enabled)
372372
MEMC_SESSION_INI_ENTRY("lock_wait_min", "150", OnUpdateLongGEZero, lock_wait_min)
373-
MEMC_SESSION_INI_ENTRY("lock_wait_max", "150", OnUpdateLongGEZero, lock_wait_max)
373+
MEMC_SESSION_INI_ENTRY("lock_wait_max", "300", OnUpdateLongGEZero, lock_wait_max)
374374
MEMC_SESSION_INI_ENTRY("lock_retries", "5", OnUpdateLong, lock_retries)
375375
MEMC_SESSION_INI_ENTRY("lock_expire", "0", OnUpdateLongGEZero, lock_expiration)
376376
#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018
@@ -4277,11 +4277,10 @@ static
42774277
PHP_GINIT_FUNCTION(php_memcached)
42784278
{
42794279
#ifdef HAVE_MEMCACHED_SESSION
4280-
42814280
php_memcached_globals->session.lock_enabled = 0;
4282-
php_memcached_globals->session.lock_wait_max = 150;
42834281
php_memcached_globals->session.lock_wait_min = 150;
4284-
php_memcached_globals->session.lock_retries = 200;
4282+
php_memcached_globals->session.lock_wait_max = 300;
4283+
php_memcached_globals->session.lock_retries = 5;
42854284
php_memcached_globals->session.lock_expiration = 30;
42864285
php_memcached_globals->session.binary_protocol_enabled = 1;
42874286
php_memcached_globals->session.consistent_hash_enabled = 1;
@@ -4296,8 +4295,8 @@ PHP_GINIT_FUNCTION(php_memcached)
42964295
php_memcached_globals->session.persistent_enabled = 0;
42974296
php_memcached_globals->session.sasl_username = NULL;
42984297
php_memcached_globals->session.sasl_password = NULL;
4299-
43004298
#endif
4299+
43014300
php_memcached_globals->memc.serializer_name = NULL;
43024301
php_memcached_globals->memc.serializer_type = SERIALIZER_DEFAULT;
43034302
php_memcached_globals->memc.compression_name = NULL;

php_memcached_session.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "php_memcached_session.h"
2020

2121
#include "Zend/zend_smart_str_public.h"
22+
#include "ext/standard/php_mt_rand.h"
2223

2324
extern ZEND_DECLARE_MODULE_GLOBALS(php_memcached)
2425

@@ -126,14 +127,22 @@ zend_bool s_lock_session(memcached_st *memc, zend_string *sid)
126127
char *lock_key;
127128
size_t lock_key_len;
128129
time_t expiration;
129-
zend_long wait_time, retries;
130+
zend_long wait_time, wait_max, retries, perturb;
130131
php_memcached_user_data *user_data = memcached_get_user_data(memc);
131132

132133
lock_key_len = spprintf(&lock_key, 0, "lock.%s", sid->val);
133134
expiration = s_lock_expiration();
134135

136+
/* Implementation for a random exponential backoff:
137+
* On the first retry, wait wait_min ms. On subsequent retries, wait
138+
* for 20% longer than the previous retry, plus a random perturbation
139+
* that is 10% of the difference between the minimum and maximum wait
140+
* times. Never wait longer than the maximum wait time.
141+
*/
135142
wait_time = MEMC_SESS_INI(lock_wait_min);
143+
wait_max = MEMC_SESS_INI(lock_wait_max);
136144
retries = MEMC_SESS_INI(lock_retries);
145+
perturb = php_mt_rand_range(0, MAX(wait_max, wait_time) - MIN(wait_max, wait_time)) / 10;
137146

138147
do {
139148
rc = memcached_add(memc, lock_key, lock_key_len, "1", sizeof ("1") - 1, expiration, 0);
@@ -149,7 +158,7 @@ zend_bool s_lock_session(memcached_st *memc, zend_string *sid)
149158
case MEMCACHED_DATA_EXISTS:
150159
if (retries > 0) {
151160
usleep(wait_time * 1000);
152-
wait_time = MIN(MEMC_SESS_INI(lock_wait_max), wait_time * 2);
161+
wait_time = MIN(wait_max, wait_time * 1.2 + perturb);
153162
}
154163
break;
155164

0 commit comments

Comments
 (0)