Skip to content

Add INI setting to choose session consistent hash (ketama or ketama_weighted) #392

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
Apr 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions memcached.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 19 additions & 1 deletion php_memcached.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 0 additions & 8 deletions php_memcached.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/*
Expand Down
15 changes: 15 additions & 0 deletions php_memcached_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
16 changes: 5 additions & 11 deletions php_memcached_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)); \
} \
Expand All @@ -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);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For some reason, the value of this macro is a randomly large number, when is should be "3" or "4". I haven't sorted out why it's not coming up correctly. printf in the OnUpdateConsistentHash function shows the expected value is set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Figured out that I was calling OnUpdateString with the integer field as the target, so the value was the actual pointer value to the string. Added an extra field to hold the string value, and a different field to hold the parsed integer value. Same pattern as the compression type INI setting.

}

if (MEMC_SESS_INI(server_failure_limit)) {
Expand Down