Skip to content

Instantly share code, notes, and snippets.

@ablyler
Created August 24, 2013 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ablyler/6331007 to your computer and use it in GitHub Desktop.
Save ablyler/6331007 to your computer and use it in GitHub Desktop.
diff --git a/memcached-2.1.0/ChangeLog b/memcached-2.1.0/ChangeLog
index 9a7280d..3502e19 100644
--- a/memcached-2.1.0/ChangeLog
+++ b/memcached-2.1.0/ChangeLog
@@ -41,8 +41,6 @@ Version 2.0.0b2
Version 2.0.0b1
---------------
- * Change the return value for non-existing keys to be NULL rather than
- 'false', affects simple get only
* Add fastlz library that provides better/faster payload compression
* Add configure switch to enable/disable JSON serialization support
* Add getAllKeys() method
diff --git a/memcached-2.1.0/README.markdown b/memcached-2.1.0/README.markdown
index 7a8041e..aaad096 100644
--- a/memcached-2.1.0/README.markdown
+++ b/memcached-2.1.0/README.markdown
@@ -1,3 +1,8 @@
+2012 Holidays
+-------------
+Committers' wishlists, if you feel like kicking in towards a gift:
+ * [Andrei's](http://given.to/profile/andreiz/wishlist/1411)
+
Description
-----------
This extension uses libmemcached library to provide API for communicating with
@@ -7,8 +12,15 @@ memcached is a high-performance, distributed memory object caching system,
generic in nature, but intended for use in speeding up dynamic web applications
by alleviating database load.
+Building
+--------
+$ phpize
+$ ./configure
+$ make
+$ make test
+
Resources
---------
* [libmemcached](http://tangent.org/552/libmemcached.html)
* [memcached](http://www.danga.com/memcached/)
- * [igbinary](http://opensource.dynamoid.com/)
+ * [igbinary](https://github.com/phadej/igbinary/)
diff --git a/memcached-2.1.0/memcached-api.php b/memcached-2.1.0/memcached-api.php
index 7552295..d7085c4 100644
--- a/memcached-2.1.0/memcached-api.php
+++ b/memcached-2.1.0/memcached-api.php
@@ -53,6 +53,8 @@ class Memcached {
const OPT_RETRY_TIMEOUT;
+ const OPT_DEAD_TIMEOUT;
+
const OPT_SND_TIMEOUT;
const OPT_RCV_TIMEOUT;
@@ -257,6 +259,14 @@ class Memcached {
public function getServerByKey( $server_key ) {}
+ public function getLastErrorMessage( ) {}
+
+ public function getLastErrorCode( ) {}
+
+ public function getLastErrorErrno( ) {}
+
+ public function getLastDisconnectedServer( ) {}
+
public function flush( $delay = 0 ) {}
public function getStats( ) {}
@@ -271,6 +281,8 @@ class Memcached {
public function isPristine( ) {}
+ public function setSaslAuthData( $username, $password ) {}
+
}
class MemcachedException extends Exception {
diff --git a/memcached-2.1.0/memcached.ini b/memcached-2.1.0/memcached.ini
index cc11b25..7c16dde 100644
--- a/memcached-2.1.0/memcached.ini
+++ b/memcached-2.1.0/memcached.ini
@@ -17,9 +17,38 @@ memcached.sess_lock_wait = 150000
; the default value is "memc.sess.key."
memcached.sess_prefix = "memc.sess.key."
+; memcached session consistent hash mode
+; if set to On, consistent hashing (libketama) is used
+; for session handling.
+; When consistent hashing is used, one can add or remove cache
+; node(s) without messing up too much with existing keys
+; default is Off
+memcached.sess_consistent_hash = Off
+
+; Allow failed memcached server to automatically be removed
+memcached.sess_remove_failed = 1
+
+; Write data to a number of additional memcached servers
+; This is "poor man's HA" as libmemcached calls it.
+; If this value is positive and sess_remove_failed is enabled
+; when a memcached server fails the session will continue to be available
+; from a replica. However, if the failed memcache server
+; becomes available again it will read the session from there
+; which could have old data or no data at all
+memcached.sess_number_of_replicas = 0
+
; memcached session binary mode
+; libmemcached replicas only work if binary mode is enabled
memcached.sess_binary = Off
+; memcached session replica read randomize
+memcached.sess_randomize_replica_read = Off
+
+; memcached connect timeout value
+; In non-blocking mode this changes the value of the timeout
+; during socket connection in milliseconds. Specifying -1 means an infinite timeout.
+memcached.sess_connect_timeout = 1000
+
; Set the compression type
; valid values are: fastlz, zlib
; the default is fastlz
@@ -55,3 +84,7 @@ memcached.compression_threshold = 2000
; The default is igbinary if available and php otherwise.
memcached.serializer = "igbinary"
+; Use SASL authentication for connections
+; valid values: On, Off
+; the default is Off
+memcached.use_sasl = Off
diff --git a/memcached-2.1.0/php_memcached.c b/memcached-2.1.0/php_memcached.c
index 90ea8ab..2023e10 100644
--- a/memcached-2.1.0/php_memcached.c
+++ b/memcached-2.1.0/php_memcached.c
@@ -89,6 +89,10 @@ typedef unsigned long int uint32_t;
# include "ext/igbinary/igbinary.h"
#endif
+#if !defined(LIBMEMCACHED_VERSION_HEX) || LIBMEMCACHED_VERSION_HEX < 0x01000002
+#error "Too old libmemcached version"
+#endif
+
/*
* This is needed because PHP 5.3.[01] does not install JSON_parser.h by default. This
* constant will move into php_json.h in the future anyway.
@@ -264,7 +268,7 @@ static PHP_INI_MH(OnUpdateSerializer)
MEMC_G(serializer) = SERIALIZER_DEFAULT;
} else if (!strcmp(new_value, "php")) {
MEMC_G(serializer) = SERIALIZER_PHP;
-#ifdef HAVE_MEMCACHE_IGBINARY
+#ifdef HAVE_MEMCACHED_IGBINARY
} else if (!strcmp(new_value, "igbinary")) {
MEMC_G(serializer) = SERIALIZER_IGBINARY;
#endif // IGBINARY
@@ -285,9 +289,15 @@ static PHP_INI_MH(OnUpdateSerializer)
PHP_INI_BEGIN()
#ifdef HAVE_MEMCACHED_SESSION
STD_PHP_INI_ENTRY("memcached.sess_locking", "1", PHP_INI_ALL, OnUpdateBool, sess_locking_enabled, zend_php_memcached_globals, php_memcached_globals)
+ STD_PHP_INI_ENTRY("memcached.sess_consistent_hash", "0", PHP_INI_ALL, OnUpdateBool, sess_consistent_hash_enabled, zend_php_memcached_globals, php_memcached_globals)
STD_PHP_INI_ENTRY("memcached.sess_binary", "0", PHP_INI_ALL, OnUpdateBool, sess_binary_enabled, zend_php_memcached_globals, php_memcached_globals)
STD_PHP_INI_ENTRY("memcached.sess_lock_wait", "150000", PHP_INI_ALL, OnUpdateLongGEZero,sess_lock_wait, zend_php_memcached_globals, php_memcached_globals)
STD_PHP_INI_ENTRY("memcached.sess_prefix", "memc.sess.key.", PHP_INI_ALL, OnUpdateString, sess_prefix, zend_php_memcached_globals, php_memcached_globals)
+
+ STD_PHP_INI_ENTRY("memcached.sess_number_of_replicas", "0", PHP_INI_ALL, OnUpdateLongGEZero, sess_number_of_replicas, zend_php_memcached_globals, php_memcached_globals)
+ STD_PHP_INI_ENTRY("memcached.sess_randomize_replica_read", "0", PHP_INI_ALL, OnUpdateBool, sess_randomize_replica_read, zend_php_memcached_globals, php_memcached_globals)
+ STD_PHP_INI_ENTRY("memcached.sess_remove_failed", "0", PHP_INI_ALL, OnUpdateBool, sess_remove_failed_enabled, zend_php_memcached_globals, php_memcached_globals)
+ STD_PHP_INI_ENTRY("memcached.sess_connect_timeout", "1000", PHP_INI_ALL, OnUpdateLong, sess_connect_timeout, zend_php_memcached_globals, php_memcached_globals)
#endif
STD_PHP_INI_ENTRY("memcached.compression_type", "fastlz", PHP_INI_ALL, OnUpdateCompressionType, compression_type, zend_php_memcached_globals, php_memcached_globals)
STD_PHP_INI_ENTRY("memcached.compression_factor", "1.3", PHP_INI_ALL, OnUpdateReal, compression_factor, zend_php_memcached_globals, php_memcached_globals)
@@ -303,7 +313,7 @@ PHP_INI_END()
/****************************************
Forward declarations
****************************************/
-static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRMLS_DC);
+static int php_memc_handle_error(php_memc_t *i_obj, memcached_return_t status TSRMLS_DC);
static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t *flags, enum memcached_serializer serializer, enum memcached_compression_type compression_type TSRMLS_DC);
static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload_len, uint32_t flags, enum memcached_serializer serializer TSRMLS_DC);
static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
@@ -313,11 +323,17 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
-static memcached_return php_memc_do_cache_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *key, size_t key_len, zval *value TSRMLS_DC);
+static memcached_return_t php_memc_do_cache_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *key, size_t key_len, zval *value TSRMLS_DC);
static int php_memc_do_result_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, memcached_result_st *result TSRMLS_DC);
-static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
-static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
-static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context);
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context);
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context);
+#else
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
+#endif
static void php_memc_destroy(struct memc_obj *m_obj, zend_bool persistent TSRMLS_DC);
/****************************************
@@ -518,7 +534,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
zend_fcall_info fci = empty_fcall_info;
zend_fcall_info_cache fcc = empty_fcall_info_cache;
memcached_result_st result;
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -631,7 +647,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
if (payload == NULL && status == MEMCACHED_NOTFOUND && fci.size != 0) {
size_t dummy_length;
uint32_t dummy_flags;
- memcached_return dummy_status;
+ memcached_return_t dummy_status;
status = php_memc_do_cache_callback(getThis(), &fci, &fcc, key, key_len,
return_value TSRMLS_CC);
@@ -700,7 +716,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
int i = 0;
zend_bool preserve_order;
memcached_result_st result;
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -875,7 +891,7 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_
zend_fcall_info fci = empty_fcall_info;
zend_fcall_info_cache fcc = empty_fcall_info_cache;
int i = 0;
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -994,7 +1010,7 @@ PHP_METHOD(Memcached, fetch)
uint32_t flags = 0;
uint64_t cas = 0;
memcached_result_st result;
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters_none() == FAILURE) {
@@ -1051,7 +1067,7 @@ PHP_METHOD(Memcached, fetchAll)
uint32_t flags;
uint64_t cas = 0;
memcached_result_st result;
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters_none() == FAILURE) {
@@ -1118,7 +1134,6 @@ PHP_METHOD(Memcached, setByKey)
}
/* }}} */
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000002
/* {{{ Memcached::touch(string key, [, int expiration ])
Sets a new expiration for the given key */
PHP_METHOD(Memcached, touch)
@@ -1134,7 +1149,6 @@ PHP_METHOD(Memcached, touchByKey)
php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 1);
}
/* }}} */
-#endif
/* {{{ Memcached::setMulti(array items [, int expiration ])
@@ -1170,6 +1184,7 @@ PHP_METHOD(Memcached, setMultiByKey)
case MEMCACHED_SERVER_MARKED_DEAD: \
if (memcached_server_count(m_obj->memc) > 0) { \
retry++; \
+ i_obj->rescode = 0; \
goto retry; \
} \
break; \
@@ -1191,7 +1206,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
size_t payload_len;
uint32_t flags = 0;
uint32_t retry = 0;
- memcached_return status;
+ memcached_return_t status;
char tmp_key[MEMCACHED_MAX_KEY];
MEMC_METHOD_INIT_VARS;
@@ -1337,7 +1352,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool
size_t payload_len;
uint32_t flags = 0;
uint32_t retry = 0;
- memcached_return status;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -1505,7 +1520,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
char *payload;
size_t payload_len;
uint32_t flags = 0;
- memcached_return status;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -1610,7 +1625,7 @@ static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
char *server_key = NULL;
int server_key_len = 0;
time_t expiration = 0;
- memcached_return status;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -1655,7 +1670,7 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by
time_t expiration = 0;
zval **entry;
- memcached_return status;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (by_key) {
@@ -1711,7 +1726,7 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key,
long offset = 1;
uint64_t value, initial = 0;
time_t expiry = 0;
- memcached_return status;
+ memcached_return_t status;
int n_args = ZEND_NUM_ARGS();
uint32_t retry = 0;
@@ -1819,7 +1834,7 @@ PHP_METHOD(Memcached, addServer)
char *host;
int host_len;
long port, weight = 0;
- memcached_return status;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &host, &host_len,
@@ -1855,8 +1870,8 @@ PHP_METHOD(Memcached, addServers)
zval **z_host, **z_port, **z_weight = NULL;
uint32_t weight = 0;
int entry_size, i = 0;
- memcached_server_st *list = NULL;
- memcached_return status;
+ memcached_server_list_st list = NULL;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &servers) == FAILURE) {
@@ -1936,7 +1951,7 @@ PHP_METHOD(Memcached, addServers)
PHP_METHOD(Memcached, getServerList)
{
struct callbackContext context = {0};
- memcached_server_function callbacks[1];
+ memcached_server_fn callbacks[1];
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters_none() == FAILURE) {
@@ -1958,8 +1973,12 @@ PHP_METHOD(Memcached, getServerByKey)
{
char *server_key;
int server_key_len;
- memcached_server_st *server;
- memcached_return error;
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
+ memcached_instance_st *server_instance;
+#else
+ memcached_server_instance_st *server_instance;
+#endif
+ memcached_return_t error;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &server_key, &server_key_len) == FAILURE) {
@@ -1974,16 +1993,15 @@ PHP_METHOD(Memcached, getServerByKey)
RETURN_FALSE;
}
- server = memcached_server_by_key(m_obj->memc, server_key, server_key_len, &error);
- if (server == NULL) {
+ server_instance = memcached_server_by_key(m_obj->memc, server_key, server_key_len, &error);
+ if (server_instance == NULL) {
php_memc_handle_error(i_obj, error TSRMLS_CC);
RETURN_FALSE;
}
array_init(return_value);
- add_assoc_string(return_value, "host", server->hostname, 1);
- add_assoc_long(return_value, "port", server->port);
- add_assoc_long(return_value, "weight", server->weight);
+ add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance), 1);
+ add_assoc_long(return_value, "port", memcached_server_port(server_instance));
}
/* }}} */
@@ -2021,14 +2039,91 @@ PHP_METHOD(Memcached, quit)
}
/* }}} */
+/* {{{ Memcached::getLastErrorMessage()
+ Returns the last error message that occurred */
+PHP_METHOD(Memcached, getLastErrorMessage)
+{
+ MEMC_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ MEMC_METHOD_FETCH_OBJECT;
+
+ RETURN_STRING(memcached_last_error_message(m_obj->memc), 1);
+}
+/* }}} */
+
+/* {{{ Memcached::getLastErrorCode()
+ Returns the last error code that occurred */
+PHP_METHOD(Memcached, getLastErrorCode)
+{
+ MEMC_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ MEMC_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(memcached_last_error(m_obj->memc));
+}
+/* }}} */
+
+/* {{{ Memcached::getLastErrorErrno()
+ Returns the last error errno that occurred */
+PHP_METHOD(Memcached, getLastErrorErrno)
+{
+ MEMC_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ MEMC_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(memcached_last_error_errno(m_obj->memc));
+}
+/* }}} */
+
+/* {{{ Memcached::getLastDisconnectedServer()
+ Returns the last disconnected server
+ Was added in 0.34 according to libmemcached's Changelog */
+PHP_METHOD(Memcached, getLastDisconnectedServer)
+{
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
+ memcached_instance_st *server_instance;
+#else
+ memcached_server_instance_st *server_instance;
+#endif
+ MEMC_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ MEMC_METHOD_FETCH_OBJECT;
+
+ server_instance = memcached_server_get_last_disconnect(m_obj->memc);
+ if (server_instance == NULL) {
+ RETURN_FALSE;
+ }
+
+ array_init(return_value);
+ add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance), 1);
+ add_assoc_long(return_value, "port", memcached_server_port(server_instance));
+}
+/* }}} */
+
/* {{{ Memcached::getStats()
Returns statistics for the memcache servers */
PHP_METHOD(Memcached, getStats)
{
memcached_stat_st *stats;
- memcached_return status;
+ memcached_return_t status;
struct callbackContext context = {0};
- memcached_server_function callbacks[1];
+ memcached_server_fn callbacks[1];
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters_none() == FAILURE) {
@@ -2067,9 +2162,9 @@ PHP_METHOD(Memcached, getStats)
Returns the version of each memcached server in the pool */
PHP_METHOD(Memcached, getVersion)
{
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
struct callbackContext context = {0};
- memcached_server_function callbacks[1];
+ memcached_server_fn callbacks[1];
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters_none() == FAILURE) {
@@ -2095,7 +2190,7 @@ PHP_METHOD(Memcached, getVersion)
/* {{{ Memcached::getAllKeys()
Returns the keys stored on all the servers */
-static memcached_return php_memc_dump_func_callback(const memcached_st *ptr __attribute__((unused)), \
+static memcached_return_t php_memc_dump_func_callback(const memcached_st *ptr __attribute__((unused)), \
const char *key, size_t key_length, void *context)
{
zval *ctx = (zval*) context;
@@ -2106,8 +2201,8 @@ static memcached_return php_memc_dump_func_callback(const memcached_st *ptr __at
PHP_METHOD(Memcached, getAllKeys)
{
- memcached_return rc;
- memcached_dump_func callback[1];
+ memcached_return_t rc;
+ memcached_dump_fn callback[1];
MEMC_METHOD_INIT_VARS;
callback[0] = php_memc_dump_func_callback;
@@ -2127,7 +2222,7 @@ PHP_METHOD(Memcached, getAllKeys)
static PHP_METHOD(Memcached, flush)
{
time_t delay = 0;
- memcached_return status;
+ memcached_return_t status;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &delay) == FAILURE) {
@@ -2152,7 +2247,7 @@ static PHP_METHOD(Memcached, getOption)
{
long option;
uint64_t result;
- memcached_behavior flag;
+ memcached_behavior_t flag;
MEMC_METHOD_INIT_VARS;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &option) == FAILURE) {
@@ -2170,16 +2265,12 @@ static PHP_METHOD(Memcached, getOption)
case MEMC_OPT_PREFIX_KEY:
{
- memcached_return retval;
+ memcached_return_t retval;
char *result;
result = memcached_callback_get(m_obj->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval);
if (retval == MEMCACHED_SUCCESS && result) {
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00050000
- RETURN_STRINGL(result, strlen(result) - 1, 1);
-#else
RETURN_STRING(result, 1);
-#endif
} else {
RETURN_EMPTY_STRING();
}
@@ -2209,7 +2300,7 @@ static PHP_METHOD(Memcached, getOption)
static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRMLS_DC)
{
- memcached_behavior flag;
+ memcached_behavior_t flag;
struct memc_obj *m_obj = i_obj->obj;
switch (option) {
@@ -2232,23 +2323,15 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
case MEMC_OPT_PREFIX_KEY:
{
char *key;
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00050000
- char tmp[MEMCACHED_PREFIX_KEY_MAX_SIZE - 1];
-#endif
convert_to_string(value);
if (Z_STRLEN_P(value) == 0) {
key = NULL;
} else {
/*
- work-around a bug in libmemcached prior to version 0.50 that truncates the trailing
+ work-around a bug in libmemcached in version 0.49 that truncates the trailing
character of the key prefix, to avoid the issue we pad it with a '0'
*/
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00050000
- snprintf(tmp, sizeof(tmp), "%s0", Z_STRVAL_P(value));
- key = tmp;
-#else
key = Z_STRVAL_P(value);
-#endif
}
if (memcached_callback_set(m_obj->memc, MEMCACHED_CALLBACK_PREFIX_KEY, key) == MEMCACHED_BAD_KEY_PROVIDED) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "bad key provided");
@@ -2272,14 +2355,9 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
* (non-weighted) case. We have to clean up ourselves.
*/
if (!Z_LVAL_P(value)) {
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX > 0x00037000
(void)memcached_behavior_set_key_hash(m_obj->memc, MEMCACHED_HASH_DEFAULT);
(void)memcached_behavior_set_distribution_hash(m_obj->memc, MEMCACHED_HASH_DEFAULT);
(void)memcached_behavior_set_distribution(m_obj->memc, MEMCACHED_DISTRIBUTION_MODULA);
-#else
- m_obj->memc->hash = 0;
- m_obj->memc->distribution = 0;
-#endif
}
break;
@@ -2317,10 +2395,7 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
flag = (memcached_behavior) option;
convert_to_long(value);
if (flag < 0 ||
-/* MEMCACHED_BEHAVIOR_MAX was added in somewhere around 0.36 or 0.37 */
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00037000
flag >= MEMCACHED_BEHAVIOR_MAX ||
-#endif
memcached_behavior_set(m_obj->memc, flag, (uint64_t)Z_LVAL_P(value)) != MEMCACHED_SUCCESS) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error setting memcached option");
return 0;
@@ -2406,6 +2481,11 @@ static PHP_METHOD(Memcached, setSaslAuthData)
return;
}
+ if (!MEMC_G(use_sasl)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SASL support (memcached.use_sasl) isn't enabled in php.ini");
+ RETURN_FALSE;
+ }
+
MEMC_METHOD_FETCH_OBJECT;
if (!memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) {
@@ -2456,13 +2536,13 @@ static PHP_METHOD(Memcached, getResultMessage)
if (i_obj->memc_errno) {
char *str;
int str_len;
- str_len = spprintf(&str, 0, "%s: %s", memcached_strerror(m_obj->memc, (memcached_return)i_obj->rescode),
+ str_len = spprintf(&str, 0, "%s: %s", memcached_strerror(m_obj->memc, (memcached_return_t)i_obj->rescode),
strerror(i_obj->memc_errno));
RETURN_STRINGL(str, str_len, 0);
}
/* Fall through */
default:
- RETURN_STRING(memcached_strerror(m_obj->memc, (memcached_return)i_obj->rescode), 1);
+ RETURN_STRING(memcached_strerror(m_obj->memc, (memcached_return_t)i_obj->rescode), 1);
break;
}
@@ -2573,24 +2653,33 @@ ZEND_RSRC_DTOR_FUNC(php_memc_sess_dtor)
/* }}} */
/* {{{ internal API functions */
-static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context)
+#else
+static memcached_return_t php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
+#endif
{
struct callbackContext* context = (struct callbackContext*) in_context;
zval *array;
MAKE_STD_ZVAL(array);
array_init(array);
- add_assoc_string(array, "host", memcached_server_name(instance), 1);
+ add_assoc_string(array, "host", (char*) memcached_server_name(instance), 1);
add_assoc_long(array, "port", memcached_server_port(instance));
/*
* API does not allow to get at this field.
add_assoc_long(array, "weight", instance->weight);
- */
+ */
+
add_next_index_zval(context->return_value, array);
return MEMCACHED_SUCCESS;
}
-static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context)
+#else
+static memcached_return_t php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
+#endif
{
char *hostport = NULL;
int hostport_len;
@@ -2634,7 +2723,11 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memc
return MEMCACHED_SUCCESS;
}
-static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context)
+#else
+static memcached_return_t php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
+#endif
{
char *hostport = NULL;
char version[16];
@@ -2642,17 +2735,24 @@ static memcached_return php_memc_do_version_callback(const memcached_st *ptr, me
struct callbackContext* context = (struct callbackContext*) in_context;
hostport_len = spprintf(&hostport, 0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance));
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009
version_len = snprintf(version, sizeof(version), "%d.%d.%d",
memcached_server_major_version(instance),
memcached_server_minor_version(instance),
memcached_server_micro_version(instance));
+#else
+ version_len = snprintf(version, sizeof(version), "%d.%d.%d",
+ instance->major_version,
+ instance->minor_version,
+ instance->micro_version);
+#endif
add_assoc_stringl_ex(context->return_value, hostport, hostport_len+1, version, version_len, 1);
efree(hostport);
return MEMCACHED_SUCCESS;
}
-static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRMLS_DC)
+static int php_memc_handle_error(php_memc_t *i_obj, memcached_return_t status TSRMLS_DC)
{
int result = 0;
@@ -2674,23 +2774,13 @@ static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRM
case MEMCACHED_SOME_ERRORS:
i_obj->rescode = status;
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000
i_obj->memc_errno = memcached_last_error_errno(i_obj->obj->memc);
-#else
- i_obj->memc_errno = i_obj->obj->memc->cached_errno; /* Hnngghgh! */
-
-#endif
result = 0;
break;
default:
i_obj->rescode = status;
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000
i_obj->memc_errno = memcached_last_error_errno(i_obj->obj->memc);
-#else
- i_obj->memc_errno = i_obj->obj->memc->cached_errno; /* Hnngghgh! */
-
-#endif
result = -1;
break;
}
@@ -3027,11 +3117,16 @@ static void php_memc_init_globals(zend_php_memcached_globals *php_memcached_glob
#ifdef HAVE_MEMCACHED_SESSION
MEMC_G(sess_locking_enabled) = 1;
MEMC_G(sess_binary_enabled) = 1;
+ MEMC_G(sess_consistent_hash_enabled) = 0;
+ MEMC_G(sess_number_of_replicas) = 0;
+ MEMC_G(sess_remove_failed_enabled) = 0;
MEMC_G(sess_prefix) = NULL;
MEMC_G(sess_lock_wait) = 0;
MEMC_G(sess_locked) = 0;
MEMC_G(sess_lock_key) = NULL;
MEMC_G(sess_lock_key_len) = 0;
+ MEMC_G(sess_randomize_replica_read) = 0;
+ MEMC_G(sess_connect_timeout) = 1000;
#endif
MEMC_G(serializer_name) = NULL;
MEMC_G(serializer) = SERIALIZER_DEFAULT;
@@ -3084,7 +3179,7 @@ zend_class_entry *php_memc_get_exception_base(int root TSRMLS_DC)
#endif
}
-static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_info *fci,
+static memcached_return_t php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_info *fci,
zend_fcall_info_cache *fcc, char *key,
size_t key_len, zval *value TSRMLS_DC)
{
@@ -3096,9 +3191,9 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i
zval *z_expiration;
uint32_t flags = 0;
- memcached_return rc;
+ memcached_return_t rc;
php_memc_t* i_obj;
- memcached_return status = MEMCACHED_SUCCESS;
+ memcached_return_t status = MEMCACHED_SUCCESS;
int result;
MAKE_STD_ZVAL(z_key);
@@ -3132,7 +3227,7 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i
payload = php_memc_zval_to_payload(value, &payload_len, &flags, m_obj->serializer, m_obj->compression_type TSRMLS_CC);
if (payload == NULL) {
- status = (memcached_return)MEMC_RES_PAYLOAD_FAILURE;
+ status = (memcached_return_t)MEMC_RES_PAYLOAD_FAILURE;
} else {
rc = memcached_set(m_obj->memc, key, key_len, payload, payload_len, expiration, flags);
if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED) {
@@ -3466,6 +3561,18 @@ ZEND_BEGIN_ARG_INFO(arginfo_getServerByKey, 0)
ZEND_ARG_INFO(0, server_key)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorMessage, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorCode, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorErrno, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_getLastDisconnectedServer, 0)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_getOption, 0)
ZEND_ARG_INFO(0, option)
ZEND_END_ARG_INFO()
@@ -3519,10 +3626,8 @@ static zend_function_entry memcached_class_methods[] = {
MEMC_ME(set, arginfo_set)
MEMC_ME(setByKey, arginfo_setByKey)
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000002
MEMC_ME(touch, arginfo_touch)
MEMC_ME(touchByKey, arginfo_touchByKey)
-#endif
MEMC_ME(setMulti, arginfo_setMulti)
MEMC_ME(setMultiByKey, arginfo_setMultiByKey)
@@ -3553,6 +3658,11 @@ static zend_function_entry memcached_class_methods[] = {
MEMC_ME(resetServerList, arginfo_resetServerList)
MEMC_ME(quit, arginfo_quit)
+ MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage)
+ MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode)
+ MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno)
+ MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer)
+
MEMC_ME(getStats, arginfo_getStats)
MEMC_ME(getVersion, arginfo_getVersion)
MEMC_ME(getAllKeys, arginfo_getAllKeys)
@@ -3677,9 +3787,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS)
REGISTER_MEMC_CLASS_CONST_LONG(OPT_DISTRIBUTION, MEMCACHED_BEHAVIOR_DISTRIBUTION);
REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_MODULA, MEMCACHED_DISTRIBUTION_MODULA);
REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_CONSISTENT, MEMCACHED_DISTRIBUTION_CONSISTENT);
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000
REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_VIRTUAL_BUCKET, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET);
-#endif
REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_COMPATIBLE, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_HASH, MEMCACHED_BEHAVIOR_KETAMA_HASH);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_KEEPALIVE, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
@@ -3691,6 +3799,9 @@ static void php_memc_register_constants(INIT_FUNC_ARGS)
REGISTER_MEMC_CLASS_CONST_LONG(OPT_SOCKET_RECV_SIZE, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_CONNECT_TIMEOUT, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_RETRY_TIMEOUT, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT);
+#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000003
+ REGISTER_MEMC_CLASS_CONST_LONG(OPT_DEAD_TIMEOUT, MEMCACHED_BEHAVIOR_DEAD_TIMEOUT);
+#endif
REGISTER_MEMC_CLASS_CONST_LONG(OPT_SEND_TIMEOUT, MEMCACHED_BEHAVIOR_SND_TIMEOUT);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_RECV_TIMEOUT, MEMCACHED_BEHAVIOR_RCV_TIMEOUT);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_POLL_TIMEOUT, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
@@ -3702,13 +3813,9 @@ static void php_memc_register_constants(INIT_FUNC_ARGS)
REGISTER_MEMC_CLASS_CONST_LONG(OPT_SORT_HOSTS, MEMCACHED_BEHAVIOR_SORT_HOSTS);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_VERIFY_KEY, MEMCACHED_BEHAVIOR_VERIFY_KEY);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_USE_UDP, MEMCACHED_BEHAVIOR_USE_UDP);
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00037000
REGISTER_MEMC_CLASS_CONST_LONG(OPT_NUMBER_OF_REPLICAS, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
REGISTER_MEMC_CLASS_CONST_LONG(OPT_RANDOMIZE_REPLICA_READ, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ);
-#endif
-#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000
REGISTER_MEMC_CLASS_CONST_LONG(OPT_REMOVE_FAILED_SERVERS, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS);
-#endif
/*
* libmemcached result codes
@@ -3870,6 +3977,12 @@ PHP_MINFO_FUNCTION(memcached)
php_info_print_table_row(2, "Version", PHP_MEMCACHED_VERSION);
php_info_print_table_row(2, "libmemcached version", memcached_lib_version());
+#if HAVE_MEMCACHED_SASL
+ php_info_print_table_row(2, "SASL support", "yes");
+#else
+ php_info_print_table_row(2, "SASL support", "no");
+#endif
+
#ifdef HAVE_MEMCACHED_SESSION
php_info_print_table_row(2, "Session support", "yes");
#else
diff --git a/memcached-2.1.0/php_memcached.h b/memcached-2.1.0/php_memcached.h
index 564b7a5..61e9c69 100644
--- a/memcached-2.1.0/php_memcached.h
+++ b/memcached-2.1.0/php_memcached.h
@@ -66,6 +66,13 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached)
zend_bool sess_locked;
char* sess_lock_key;
int sess_lock_key_len;
+
+ int sess_number_of_replicas;
+ zend_bool sess_randomize_replica_read;
+ zend_bool sess_remove_failed_enabled;
+ long sess_connect_timeout;
+ zend_bool sess_consistent_hash_enabled;
+ zend_bool sess_binary_enabled;
#endif
char *serializer_name;
enum memcached_serializer serializer;
@@ -78,7 +85,6 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached)
#if HAVE_MEMCACHED_SASL
bool use_sasl;
#endif
- zend_bool sess_binary_enabled;
ZEND_END_MODULE_GLOBALS(php_memcached)
PHP_MEMCACHED_API zend_class_entry *php_memc_get_ce(void);
diff --git a/memcached-2.1.0/php_memcached_session.c b/memcached-2.1.0/php_memcached_session.c
index 0dca515..952b744 100644
--- a/memcached-2.1.0/php_memcached_session.c
+++ b/memcached-2.1.0/php_memcached_session.c
@@ -48,6 +48,7 @@ static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC)
char *lock_key = NULL;
int lock_key_len = 0;
unsigned long attempts;
+ long write_retry_attempts = 0;
long lock_maxwait;
long lock_wait = MEMC_G(sess_lock_wait);
time_t expiration;
@@ -64,6 +65,11 @@ static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC)
expiration = time(NULL) + lock_maxwait + 1;
attempts = (unsigned long)((1000000.0 / lock_wait) * lock_maxwait);
+ /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server */
+ if (MEMC_G(sess_remove_failed_enabled)) {
+ write_retry_attempts = MEMC_G(sess_number_of_replicas) * ( memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT) + 1);
+ }
+
lock_key_len = spprintf(&lock_key, 0, "lock.%s", key);
do {
status = memcached_add(memc, lock_key, lock_key_len, "1", sizeof("1")-1, expiration, 0);
@@ -73,6 +79,11 @@ static int php_memc_sess_lock(memcached_st *memc, const char *key TSRMLS_DC)
MEMC_G(sess_lock_key_len) = lock_key_len;
return 0;
} else if (status != MEMCACHED_NOTSTORED && status != MEMCACHED_DATA_EXISTS) {
+ if (write_retry_attempts > 0) {
+ write_retry_attempts--;
+ continue;
+ }
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Write of lock failed");
break;
}
@@ -139,10 +150,22 @@ error:
if (servers) {
memc_sess->memc_sess = memcached_create(NULL);
if (memc_sess->memc_sess) {
+ if (MEMC_G(sess_consistent_hash_enabled)) {
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, (uint64_t) 1) == MEMCACHED_FAILURE) {
+ PS_SET_MOD_DATA(NULL);
+ if (plist_key) {
+ efree(plist_key);
+ }
+ memcached_free(memc_sess->memc_sess);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to enable memcached consistent hashing");
+ return FAILURE;
+ }
+ }
+
status = memcached_server_push(memc_sess->memc_sess, servers);
memcached_server_list_free(servers);
- if (memcached_callback_set(memc_sess->memc_sess, MEMCACHED_CALLBACK_PREFIX_KEY, MEMC_G(sess_prefix)) != MEMCACHED_SUCCESS) {
+ if (MEMC_G(sess_prefix) && MEMC_G(sess_prefix)[0] != 0 && memcached_callback_set(memc_sess->memc_sess, MEMCACHED_CALLBACK_PREFIX_KEY, MEMC_G(sess_prefix)) != MEMCACHED_SUCCESS) {
PS_SET_MOD_DATA(NULL);
if (plist_key) {
efree(plist_key);
@@ -195,6 +218,29 @@ success:
}
}
+ if (MEMC_G(sess_number_of_replicas) > 0) {
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, (uint64_t) MEMC_G(sess_number_of_replicas)) == MEMCACHED_FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set memcached session number of replicas");
+ return FAILURE;
+ }
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, (uint64_t) MEMC_G(sess_randomize_replica_read)) == MEMCACHED_FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set memcached session randomize replica read");
+ }
+ }
+
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, (uint64_t) MEMC_G(sess_connect_timeout)) == MEMCACHED_FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set memcached connection timeout");
+ return FAILURE;
+ }
+
+ /* Allow libmemcached remove failed servers */
+ if (MEMC_G(sess_remove_failed_enabled)) {
+ if (memcached_behavior_set(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, (uint64_t) 1) == MEMCACHED_FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set: remove failed servers");
+ return FAILURE;
+ }
+ }
+
return SUCCESS;
}
}
@@ -243,6 +289,7 @@ PS_READ_FUNC(memcached)
if (MEMC_G(sess_locking_enabled)) {
if (php_memc_sess_lock(memc_sess->memc_sess, key TSRMLS_CC) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to clear session lock record");
return FAILURE;
}
}
@@ -263,6 +310,7 @@ PS_WRITE_FUNC(memcached)
{
int key_len = strlen(key);
time_t expiration = 0;
+ long write_try_attempts = 1;
memcached_return status;
memcached_sess *memc_sess = PS_GET_MOD_DATA();
size_t key_length;
@@ -277,13 +325,22 @@ PS_WRITE_FUNC(memcached)
if (PS(gc_maxlifetime) > 0) {
expiration = PS(gc_maxlifetime);
}
- status = memcached_set(memc_sess->memc_sess, key, key_len, val, vallen, expiration, 0);
- if (status == MEMCACHED_SUCCESS) {
- return SUCCESS;
- } else {
- return FAILURE;
+ /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server plus the initial write */
+ if (MEMC_G(sess_remove_failed_enabled)) {
+ write_try_attempts = 1 + MEMC_G(sess_number_of_replicas) * ( memcached_behavior_get(memc_sess->memc_sess, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT) + 1);
}
+
+ do {
+ status = memcached_set(memc_sess->memc_sess, key, key_len, val, vallen, expiration, 0);
+ if (status == MEMCACHED_SUCCESS) {
+ return SUCCESS;
+ } else {
+ write_try_attempts--;
+ }
+ } while (write_try_attempts > 0);
+
+ return FAILURE;
}
PS_DESTROY_FUNC(memcached)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment