diff options
-rw-r--r-- | cluster_library.c | 82 | ||||
-rw-r--r-- | cluster_library.h | 2 | ||||
-rw-r--r-- | redis_cluster.c | 80 | ||||
-rw-r--r-- | redis_session.c | 14 |
4 files changed, 96 insertions, 82 deletions
diff --git a/cluster_library.c b/cluster_library.c index 0dcad152..47c0c52b 100644 --- a/cluster_library.c +++ b/cluster_library.c @@ -7,6 +7,7 @@ #include <zend_exceptions.h> extern zend_class_entry *redis_cluster_exception_ce; +int le_cluster_slot_cache; /* Debugging methods/ static void cluster_dump_nodes(redisCluster *c) { @@ -2767,4 +2768,85 @@ int mbulk_resp_loop_assoc(RedisSock *redis_sock, zval *z_result, return SUCCESS; } +/* Turn a seed array into a zend_string we can use to look up a slot cache */ +zend_string *cluster_hash_seeds(HashTable *ht) { + smart_str hash = {0}; + zend_string *zstr; + zval *z_seed; + + ZEND_HASH_FOREACH_VAL(ht, z_seed) { + zstr = zval_get_string(z_seed); + smart_str_appendc(&hash, '['); + smart_str_appendl(&hash, ZSTR_VAL(zstr), ZSTR_LEN(zstr)); + smart_str_appendc(&hash, ']'); + zend_string_release(zstr); + } ZEND_HASH_FOREACH_END(); + + /* Not strictly needed but null terminate anyway */ + smart_str_0(&hash); + + /* smart_str is a zend_string internally */ + return hash.s; +} + + +#define SLOT_CACHING_ENABLED() (INI_INT("redis.clusters.cache_slots") == 1) +PHP_REDIS_API redisCachedCluster *cluster_cache_load(HashTable *ht_seeds) { + zend_resource *le; + zend_string *h; + + /* Short circuit if we're not caching slots or if our seeds don't have any + * elements, since it doesn't make sense to cache an empty string */ + if (!SLOT_CACHING_ENABLED() || zend_hash_num_elements(ht_seeds) == 0) + return NULL; + + /* Look for cached slot information */ + h = cluster_hash_seeds(ht_seeds); + le = zend_hash_str_find_ptr(&EG(persistent_list), ZSTR_VAL(h), ZSTR_LEN(h)); + zend_string_release(h); + + if (le != NULL) { + /* Sanity check on our list type */ + if (le->type != le_cluster_slot_cache) { + php_error_docref(0, E_WARNING, "Invalid slot cache resource"); + return NULL; + } + + /* Success, return the cached entry */ + return le->ptr; + } + + /* Not found */ + return NULL; +} + +/* Cache a cluster's slot information in persistent_list if it's enabled */ +PHP_REDIS_API int cluster_cache_store(HashTable *ht_seeds, HashTable *nodes) { + redisCachedCluster *cc; + zend_string *hash; + + /* Short circuit if caching is disabled or there aren't any seeds */ + if (!SLOT_CACHING_ENABLED() || zend_hash_num_elements(ht_seeds) == 0) + return !SLOT_CACHING_ENABLED() ? SUCCESS : FAILURE; + + /* Construct our cache */ + hash = cluster_hash_seeds(ht_seeds); + cc = cluster_cache_create(hash, nodes); + zend_string_release(hash); + + /* Set up our resource */ +#if PHP_VERSION_ID < 70300 + zend_resource le; + le.type = le_cluster_slot_cache; + le.ptr = cc; + + zend_hash_update_mem(&EG(persistent_list), cc->hash, (void*)&le, sizeof(zend_resource)); +#else + zend_register_persistent_resource_ex(cc->hash, cc, le_cluster_slot_cache); +#endif + + return SUCCESS; +} + + /* vim: set tabstop=4 softtabstop=4 expandtab shiftwidth=4: */ diff --git a/cluster_library.h b/cluster_library.h index fa3bdc11..2f6d6d8b 100644 --- a/cluster_library.h +++ b/cluster_library.h @@ -397,6 +397,8 @@ PHP_REDIS_API void cluster_init_cache(redisCluster *c, redisCachedCluster *rcc); PHP_REDIS_API char **cluster_sock_read_multibulk_reply(RedisSock *redis_sock, int *len); +PHP_REDIS_API int cluster_cache_store(HashTable *ht_seeds, HashTable *nodes); +PHP_REDIS_API redisCachedCluster *cluster_cache_load(HashTable *ht_seeds); /* * Redis Cluster response handlers. Our response handlers generally take the diff --git a/redis_cluster.c b/redis_cluster.c index 859e1414..429f771c 100644 --- a/redis_cluster.c +++ b/redis_cluster.c @@ -33,7 +33,6 @@ #include <SAPI.h> zend_class_entry *redis_cluster_ce; -int le_cluster_slot_cache; /* Exception handler */ zend_class_entry *redis_cluster_exception_ce; @@ -343,85 +342,6 @@ void free_cluster_context(zend_object *object) { zend_object_std_dtor(&cluster->std); } -/* Turn a seed array into a zend_string we can use to look up a slot cache */ -static zend_string *cluster_hash_seeds(HashTable *ht) { - smart_str hash = {0}; - zend_string *zstr; - zval *z_seed; - - ZEND_HASH_FOREACH_VAL(ht, z_seed) { - zstr = zval_get_string(z_seed); - smart_str_appendc(&hash, '['); - smart_str_appendl(&hash, ZSTR_VAL(zstr), ZSTR_LEN(zstr)); - smart_str_appendc(&hash, ']'); - zend_string_release(zstr); - } ZEND_HASH_FOREACH_END(); - - /* Not strictly needed but null terminate anyway */ - smart_str_0(&hash); - - /* smart_str is a zend_string internally */ - return hash.s; -} - -#define SLOT_CACHING_ENABLED() (INI_INT("redis.clusters.cache_slots") == 1) -static redisCachedCluster *cluster_cache_load(HashTable *ht_seeds) { - zend_resource *le; - zend_string *h; - - /* Short circuit if we're not caching slots or if our seeds don't have any - * elements, since it doesn't make sense to cache an empty string */ - if (!SLOT_CACHING_ENABLED() || zend_hash_num_elements(ht_seeds) == 0) - return NULL; - - /* Look for cached slot information */ - h = cluster_hash_seeds(ht_seeds); - le = zend_hash_str_find_ptr(&EG(persistent_list), ZSTR_VAL(h), ZSTR_LEN(h)); - zend_string_release(h); - - if (le != NULL) { - /* Sanity check on our list type */ - if (le->type != le_cluster_slot_cache) { - php_error_docref(0, E_WARNING, "Invalid slot cache resource"); - return NULL; - } - - /* Success, return the cached entry */ - return le->ptr; - } - - /* Not found */ - return NULL; -} - -/* Cache a cluster's slot information in persistent_list if it's enabled */ -static int cluster_cache_store(HashTable *ht_seeds, HashTable *nodes) { - redisCachedCluster *cc; - zend_string *hash; - - /* Short circuit if caching is disabled or there aren't any seeds */ - if (!SLOT_CACHING_ENABLED() || zend_hash_num_elements(ht_seeds) == 0) - return !SLOT_CACHING_ENABLED() ? SUCCESS : FAILURE; - - /* Construct our cache */ - hash = cluster_hash_seeds(ht_seeds); - cc = cluster_cache_create(hash, nodes); - zend_string_release(hash); - - /* Set up our resource */ -#if PHP_VERSION_ID < 70300 - zend_resource le; - le.type = le_cluster_slot_cache; - le.ptr = cc; - - zend_hash_update_mem(&EG(persistent_list), cc->hash, (void*)&le, sizeof(zend_resource)); -#else - zend_register_persistent_resource_ex(cc->hash, cc, le_cluster_slot_cache); -#endif - - return SUCCESS; -} - /* Validate redis cluster construction arguments */ static int cluster_validate_args(double timeout, double read_timeout, HashTable *seeds) { diff --git a/redis_session.c b/redis_session.c index 6bb94c60..3f8d039e 100644 --- a/redis_session.c +++ b/redis_session.c @@ -959,10 +959,20 @@ PS_OPEN_FUNC(rediscluster) { if (auth && auth_len > 0) { c->auth = zend_string_init(auth, auth_len, 0); } - if (!cluster_init_seeds(c, ht_seeds) && !cluster_map_keyspace(c)) { + + redisCachedCluster *cc; + + /* Attempt to load from cache */ + if ((cc = cluster_cache_load(ht_seeds))) { + cluster_init_cache(c, cc); /* Set up our prefix */ c->flags->prefix = zend_string_init(prefix, prefix_len, 0); - + PS_SET_MOD_DATA(c); + retval = SUCCESS; + } else if (!cluster_init_seeds(c, ht_seeds) && !cluster_map_keyspace(c)) { + /* Set up our prefix */ + c->flags->prefix = zend_string_init(prefix, prefix_len, 0); + cluster_cache_store(ht_seeds, c->nodes); PS_SET_MOD_DATA(c); retval = SUCCESS; } else { |