Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Booth <michael.booth2@skybettingandgaming.com>2019-12-02 12:00:12 +0300
committerMichael Booth <michael.booth2@skybettingandgaming.com>2019-12-02 12:00:12 +0300
commit23b1a9d84caed3e9bd64b9cc1b7b0b0cf2a7861a (patch)
treef8f88f04e8229220d4b9ba5fcb13aa22733ce8e2 /cluster_library.c
parent5c7bc3995d9c3dc080f3f9c8fd7086e07d2a4163 (diff)
Enable slot caching for session cluster
Diffstat (limited to 'cluster_library.c')
-rw-r--r--cluster_library.c82
1 files changed, 82 insertions, 0 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: */