diff --git a/memcached.ini b/memcached.ini index e4256c10..138fd09a 100644 --- a/memcached.ini +++ b/memcached.ini @@ -43,6 +43,13 @@ ; default is On ;memcached.sess_consistent_hash = On +; memcached session consistent hash type +; if set to 'ketama', consistent hashing (libketama) is used +; for session handling (default for php-memcached 3.x) +; if set to 'ketama_weighted', weighted consistent hashing (libketama) is used +; for session handling (default for php-memcached 2.x) +;memcached.sess_consistent_hash_type = "ketama" + ; Allow failed memcached server to automatically be removed. ; Default is Off. (In previous versions, this setting was called memcached.sess_remove_failed) ;memcached.sess_remove_failed_servers = Off diff --git a/php_memcached.c b/php_memcached.c index bd0f559e..c24e58af 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -323,6 +323,22 @@ PHP_INI_MH(OnUpdateSessionPrefixString) return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } +static +PHP_INI_MH(OnUpdateConsistentHash) +{ + if (!new_value) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; + } else if (!strcmp(ZSTR_VAL(new_value), "ketama")) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; + } else if (!strcmp(ZSTR_VAL(new_value), "ketama_weighted")) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED; + } else { + php_error_docref(NULL, E_WARNING, "memcached.sess_consistent_hash_type must be ketama or ketama_weighted"); + return FAILURE; + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + #define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \ STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) @@ -357,6 +373,7 @@ PHP_INI_BEGIN() MEMC_SESSION_INI_BOOL ("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) #endif MEMC_SESSION_INI_BOOL ("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) + MEMC_SESSION_INI_ENTRY("consistent_hash_type", "ketama", OnUpdateConsistentHash, consistent_hash_name) MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) @@ -1254,7 +1271,6 @@ static PHP_METHOD(Memcached, __construct) /* Set default behaviors */ if (MEMC_G(default_behavior.consistent_hash_enabled)) { - memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); if (rc != MEMCACHED_SUCCESS) { 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) php_memcached_globals->session.lock_expiration = 30; php_memcached_globals->session.binary_protocol_enabled = 1; php_memcached_globals->session.consistent_hash_enabled = 1; + php_memcached_globals->session.consistent_hash_type = MEMCACHED_BEHAVIOR_KETAMA; + php_memcached_globals->session.consistent_hash_name = NULL; php_memcached_globals->session.number_of_replicas = 0; php_memcached_globals->session.server_failure_limit = 1; php_memcached_globals->session.randomize_replica_read_enabled = 1; diff --git a/php_memcached.h b/php_memcached.h index 5194c038..a33f8be6 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -42,14 +42,6 @@ PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root); extern zend_module_entry memcached_module_entry; #define phpext_memcached_ptr &memcached_module_entry -#ifdef ZTS -#define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) -#define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) -#else -#define MEMC_G(v) (php_memcached_globals.memc.v) -#define MEMC_SERVER_G(v) (php_memcached_globals.server.v) -#endif - #endif /* PHP_MEMCACHED_H */ /* diff --git a/php_memcached_private.h b/php_memcached_private.h index abc0459c..cf652e39 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -156,6 +156,8 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) zend_bool binary_protocol_enabled; zend_bool consistent_hash_enabled; + char *consistent_hash_name; + int consistent_hash_type; zend_long server_failure_limit; zend_long number_of_replicas; @@ -207,6 +209,19 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) ZEND_END_MODULE_GLOBALS(php_memcached) +/* Globals accessor macros */ +#ifdef ZTS +# define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) +# define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) +# define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v) +#else +# define MEMC_G(v) (php_memcached_globals.memc.v) +# define MEMC_SERVER_G(v) (php_memcached_globals.server.v) +# define MEMC_SESS_INI(v) (php_memcached_globals.session.v) +#endif + +#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL) + PHP_RINIT_FUNCTION(memcached); PHP_RSHUTDOWN_FUNCTION(memcached); PHP_MINIT_FUNCTION(memcached); diff --git a/php_memcached_session.c b/php_memcached_session.c index 607a02c2..7d072af2 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -43,14 +43,6 @@ typedef struct { # define MAX(a,b) (((a)>(b))?(a):(b)) #endif -#ifdef ZTS -#define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v) -#else -#define MEMC_SESS_INI(v) (php_memcached_globals.session.v) -#endif - -#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL) - static int le_memc_sess; @@ -187,9 +179,11 @@ static zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) { #define check_set_behavior(behavior, value) \ - if ((value) != memcached_behavior_get(memc, (behavior))) { \ + int b = (behavior); \ + uint64_t v = (value); \ + if (v != memcached_behavior_get(memc, b)) { \ memcached_return rc; \ - if ((rc = memcached_behavior_set(memc, (behavior), (value))) != MEMCACHED_SUCCESS) { \ + if ((rc = memcached_behavior_set(memc, b, v)) != MEMCACHED_SUCCESS) { \ if (!silent) { \ php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); \ } \ @@ -202,7 +196,7 @@ zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) } if (MEMC_SESS_INI(consistent_hash_enabled)) { - check_set_behavior(MEMCACHED_BEHAVIOR_KETAMA, 1); + check_set_behavior(MEMC_SESS_INI(consistent_hash_type), 1); } if (MEMC_SESS_INI(server_failure_limit)) {