diff options
author | Michael Booth <michael.booth2@skybettingandgaming.com> | 2019-12-02 12:00:12 +0300 |
---|---|---|
committer | Michael Booth <michael.booth2@skybettingandgaming.com> | 2019-12-02 12:00:12 +0300 |
commit | 23b1a9d84caed3e9bd64b9cc1b7b0b0cf2a7861a (patch) | |
tree | f8f88f04e8229220d4b9ba5fcb13aa22733ce8e2 /cluster_library.c | |
parent | 5c7bc3995d9c3dc080f3f9c8fd7086e07d2a4163 (diff) |
Enable slot caching for session cluster
Diffstat (limited to 'cluster_library.c')
-rw-r--r-- | cluster_library.c | 82 |
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: */ |