Skip to content

Commit f4dafd2

Browse files
committed
Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#392)
Provides a new INI option to select the same consistent hash behavior as older versions of php-memcached, to aid in migration from PHP 5.x to PHP 7.x. When `memcached_sess_consistent_hash_type` is set to `ketama` or `ketama_weighted`, that sets either MEMCACHED_BEHAVIOR_KETAMA or MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, respectively. Resolves #344
1 parent 893d7d5 commit f4dafd2

5 files changed

+46
-20
lines changed

Diff for: memcached.ini

+7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
; default is On
4444
;memcached.sess_consistent_hash = On
4545

46+
; memcached session consistent hash type
47+
; if set to 'ketama', consistent hashing (libketama) is used
48+
; for session handling (default for php-memcached 3.x)
49+
; if set to 'ketama_weighted', weighted consistent hashing (libketama) is used
50+
; for session handling (default for php-memcached 2.x)
51+
;memcached.sess_consistent_hash_type = "ketama"
52+
4653
; Allow failed memcached server to automatically be removed.
4754
; Default is Off. (In previous versions, this setting was called memcached.sess_remove_failed)
4855
;memcached.sess_remove_failed_servers = Off

Diff for: php_memcached.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,22 @@ PHP_INI_MH(OnUpdateSessionPrefixString)
323323
return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
324324
}
325325

326+
static
327+
PHP_INI_MH(OnUpdateConsistentHash)
328+
{
329+
if (!new_value) {
330+
MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA;
331+
} else if (!strcmp(ZSTR_VAL(new_value), "ketama")) {
332+
MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA;
333+
} else if (!strcmp(ZSTR_VAL(new_value), "ketama_weighted")) {
334+
MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED;
335+
} else {
336+
php_error_docref(NULL, E_WARNING, "memcached.sess_consistent_hash_type must be ketama or ketama_weighted");
337+
return FAILURE;
338+
}
339+
return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
340+
}
341+
326342
#define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \
327343
STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals)
328344

@@ -357,6 +373,7 @@ PHP_INI_BEGIN()
357373
MEMC_SESSION_INI_BOOL ("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled)
358374
#endif
359375
MEMC_SESSION_INI_BOOL ("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled)
376+
MEMC_SESSION_INI_ENTRY("consistent_hash_type", "ketama", OnUpdateConsistentHash, consistent_hash_name)
360377
MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas)
361378
MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled)
362379
MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled)
@@ -1254,7 +1271,6 @@ static PHP_METHOD(Memcached, __construct)
12541271

12551272
/* Set default behaviors */
12561273
if (MEMC_G(default_behavior.consistent_hash_enabled)) {
1257-
12581274
memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT);
12591275
if (rc != MEMCACHED_SUCCESS) {
12601276
php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc));
@@ -4263,6 +4279,8 @@ PHP_GINIT_FUNCTION(php_memcached)
42634279
php_memcached_globals->session.lock_expiration = 30;
42644280
php_memcached_globals->session.binary_protocol_enabled = 1;
42654281
php_memcached_globals->session.consistent_hash_enabled = 1;
4282+
php_memcached_globals->session.consistent_hash_type = MEMCACHED_BEHAVIOR_KETAMA;
4283+
php_memcached_globals->session.consistent_hash_name = NULL;
42664284
php_memcached_globals->session.number_of_replicas = 0;
42674285
php_memcached_globals->session.server_failure_limit = 1;
42684286
php_memcached_globals->session.randomize_replica_read_enabled = 1;

Diff for: php_memcached.h

-8
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,6 @@ PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root);
4242
extern zend_module_entry memcached_module_entry;
4343
#define phpext_memcached_ptr &memcached_module_entry
4444

45-
#ifdef ZTS
46-
#define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v)
47-
#define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v)
48-
#else
49-
#define MEMC_G(v) (php_memcached_globals.memc.v)
50-
#define MEMC_SERVER_G(v) (php_memcached_globals.server.v)
51-
#endif
52-
5345
#endif /* PHP_MEMCACHED_H */
5446

5547
/*

Diff for: php_memcached_private.h

+15
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached)
156156

157157
zend_bool binary_protocol_enabled;
158158
zend_bool consistent_hash_enabled;
159+
char *consistent_hash_name;
160+
int consistent_hash_type;
159161

160162
zend_long server_failure_limit;
161163
zend_long number_of_replicas;
@@ -207,6 +209,19 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached)
207209

208210
ZEND_END_MODULE_GLOBALS(php_memcached)
209211

212+
/* Globals accessor macros */
213+
#ifdef ZTS
214+
# define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v)
215+
# define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v)
216+
# define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v)
217+
#else
218+
# define MEMC_G(v) (php_memcached_globals.memc.v)
219+
# define MEMC_SERVER_G(v) (php_memcached_globals.server.v)
220+
# define MEMC_SESS_INI(v) (php_memcached_globals.session.v)
221+
#endif
222+
223+
#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL)
224+
210225
PHP_RINIT_FUNCTION(memcached);
211226
PHP_RSHUTDOWN_FUNCTION(memcached);
212227
PHP_MINIT_FUNCTION(memcached);

Diff for: php_memcached_session.c

+5-11
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,6 @@ typedef struct {
4343
# define MAX(a,b) (((a)>(b))?(a):(b))
4444
#endif
4545

46-
#ifdef ZTS
47-
#define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v)
48-
#else
49-
#define MEMC_SESS_INI(v) (php_memcached_globals.session.v)
50-
#endif
51-
52-
#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL)
53-
5446
static
5547
int le_memc_sess;
5648

@@ -187,9 +179,11 @@ static
187179
zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent)
188180
{
189181
#define check_set_behavior(behavior, value) \
190-
if ((value) != memcached_behavior_get(memc, (behavior))) { \
182+
int b = (behavior); \
183+
uint64_t v = (value); \
184+
if (v != memcached_behavior_get(memc, b)) { \
191185
memcached_return rc; \
192-
if ((rc = memcached_behavior_set(memc, (behavior), (value))) != MEMCACHED_SUCCESS) { \
186+
if ((rc = memcached_behavior_set(memc, b, v)) != MEMCACHED_SUCCESS) { \
193187
if (!silent) { \
194188
php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); \
195189
} \
@@ -202,7 +196,7 @@ zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent)
202196
}
203197

204198
if (MEMC_SESS_INI(consistent_hash_enabled)) {
205-
check_set_behavior(MEMCACHED_BEHAVIOR_KETAMA, 1);
199+
check_set_behavior(MEMC_SESS_INI(consistent_hash_type), 1);
206200
}
207201

208202
if (MEMC_SESS_INI(server_failure_limit)) {

0 commit comments

Comments
 (0)