diff options
Diffstat (limited to 'examples/redis-unstable/tests/modules/atomicslotmigration.c')
| -rw-r--r-- | examples/redis-unstable/tests/modules/atomicslotmigration.c | 594 |
1 files changed, 0 insertions, 594 deletions
diff --git a/examples/redis-unstable/tests/modules/atomicslotmigration.c b/examples/redis-unstable/tests/modules/atomicslotmigration.c deleted file mode 100644 index 83393cd..0000000 --- a/examples/redis-unstable/tests/modules/atomicslotmigration.c +++ /dev/null @@ -1,594 +0,0 @@ -#include "redismodule.h" - -#include <stdlib.h> -#include <memory.h> -#include <errno.h> - -#define MAX_EVENTS 1024 - -/* Log of cluster events. */ -const char *clusterEventLog[MAX_EVENTS]; -int numClusterEvents = 0; - -/* Log of cluster trim events. */ -const char *clusterTrimEventLog[MAX_EVENTS]; -int numClusterTrimEvents = 0; - -/* Log of last deleted key event. */ -const char *lastDeletedKeyLog = NULL; - -/* Flag to disable trim. */ -int disableTrimFlag = 0; - -int replicateModuleCommand = 0; /* Enable or disable module command replication. */ -RedisModuleString *moduleCommandKeyName = NULL; /* Key name to replicate. */ -RedisModuleString *moduleCommandKeyVal = NULL; /* Key value to replicate. */ - -/* Enable or disable module command replication. */ -int replicate_module_command(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 4) { - RedisModule_ReplyWithError(ctx, "ERR wrong number of arguments"); - return REDISMODULE_OK; - } - - long long enable = 0; - if (RedisModule_StringToLongLong(argv[1], &enable) != REDISMODULE_OK) { - RedisModule_ReplyWithError(ctx, "ERR enable value"); - return REDISMODULE_OK; - } - replicateModuleCommand = (enable != 0); - - /* Set the key name and value to replicate. */ - if (moduleCommandKeyName) RedisModule_FreeString(ctx, moduleCommandKeyName); - if (moduleCommandKeyVal) RedisModule_FreeString(ctx, moduleCommandKeyVal); - moduleCommandKeyName = RedisModule_CreateStringFromString(ctx, argv[2]); - moduleCommandKeyVal = RedisModule_CreateStringFromString(ctx, argv[3]); - - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -int lpush_and_replicate_crossslot_command(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 3) return RedisModule_WrongArity(ctx); - - /* LPUSH */ - RedisModuleCallReply *rep = RedisModule_Call(ctx, "LPUSH", "!ss", argv[1], argv[2]); - RedisModule_Assert(RedisModule_CallReplyType(rep) != REDISMODULE_REPLY_ERROR); - RedisModule_FreeCallReply(rep); - - /* Replicate cross slot command */ - int ret = RedisModule_Replicate(ctx, "MSET", "cccccc", "key1", "val1", "key2", "val2", "key3", "val3"); - RedisModule_Assert(ret == REDISMODULE_OK); - - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -int testClusterGetLocalSlotRanges(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - static int use_auto_memory = 0; - use_auto_memory = !use_auto_memory; - - RedisModuleSlotRangeArray *slots; - if (use_auto_memory) { - RedisModule_AutoMemory(ctx); - slots = RedisModule_ClusterGetLocalSlotRanges(ctx); - } else { - slots = RedisModule_ClusterGetLocalSlotRanges(NULL); - } - - RedisModule_ReplyWithArray(ctx, slots->num_ranges); - for (int i = 0; i < slots->num_ranges; i++) { - RedisModule_ReplyWithArray(ctx, 2); - RedisModule_ReplyWithLongLong(ctx, slots->ranges[i].start); - RedisModule_ReplyWithLongLong(ctx, slots->ranges[i].end); - } - if (!use_auto_memory) - RedisModule_ClusterFreeSlotRanges(NULL, slots); - return REDISMODULE_OK; -} - -/* Helper function to check if a slot range array contains a given slot. */ -int slotRangeArrayContains(RedisModuleSlotRangeArray *sra, unsigned int slot) { - for (int i = 0; i < sra->num_ranges; i++) - if (sra->ranges[i].start <= slot && sra->ranges[i].end >= slot) - return 1; - return 0; -} - -/* Sanity check. */ -int sanity(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - RedisModule_Assert(RedisModule_ClusterCanAccessKeysInSlot(-1) == 0); - RedisModule_Assert(RedisModule_ClusterCanAccessKeysInSlot(16384) == 0); - RedisModule_Assert(RedisModule_ClusterCanAccessKeysInSlot(100000) == 0); - - /* Call with invalid args. */ - errno = 0; - RedisModule_Assert(RedisModule_ClusterPropagateForSlotMigration(NULL, NULL, NULL) == REDISMODULE_ERR); - RedisModule_Assert(errno == EINVAL); - - /* Call with invalid args. */ - errno = 0; - RedisModule_Assert(RedisModule_ClusterPropagateForSlotMigration(ctx, NULL, NULL) == REDISMODULE_ERR); - RedisModule_Assert(errno == EINVAL); - - /* Call with invalid args. */ - errno = 0; - RedisModule_Assert(RedisModule_ClusterPropagateForSlotMigration(NULL, "asm.keyless_cmd", "") == REDISMODULE_ERR); - RedisModule_Assert(errno == EINVAL); - - /* Call outside of slot migration. */ - errno = 0; - RedisModule_Assert(RedisModule_ClusterPropagateForSlotMigration(ctx, "asm.keyless_cmd", "") == REDISMODULE_ERR); - RedisModule_Assert(errno == EBADF); - - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -/* Command to test RM_ClusterCanAccessKeysInSlot(). */ -int testClusterCanAccessKeysInSlot(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argc); - long long slot = 0; - - if (RedisModule_StringToLongLong(argv[1],&slot) != REDISMODULE_OK) { - return RedisModule_ReplyWithError(ctx,"ERR invalid slot"); - } - RedisModule_ReplyWithLongLong(ctx, RedisModule_ClusterCanAccessKeysInSlot(slot)); - return REDISMODULE_OK; -} - -/* Generate a string representation of the info struct and subevent. - e.g. 'sub: cluster-slot-migration-import-started, task_id: aeBd..., slots: 0-100,200-300' */ -const char *clusterAsmInfoToString(RedisModuleClusterSlotMigrationInfo *info, uint64_t sub) { - char buf[1024] = {0}; - - if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_IMPORT_STARTED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-import-started, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_IMPORT_FAILED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-import-failed, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_IMPORT_COMPLETED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-import-completed, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_MIGRATE_STARTED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-migrate-started, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_MIGRATE_FAILED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-migrate-failed, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_MIGRATE_COMPLETED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-migrate-completed, "); - else { - RedisModule_Assert(0); - } - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "source_node_id:%.40s, destination_node_id:%.40s, ", - info->source_node_id, info->destination_node_id); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "task_id:%s, slots:", info->task_id); - for (int i = 0; i < info->slots->num_ranges; i++) { - RedisModuleSlotRange *sr = &info->slots->ranges[i]; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%d-%d", sr->start, sr->end); - if (i != info->slots->num_ranges - 1) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ","); - } - return RedisModule_Strdup(buf); -} - -/* Generate a string representation of the info struct and subevent. - e.g. 'sub: cluster-slot-migration-trim-started, task_id: aeBd..., slots:0-100,200-300' */ -const char *clusterTrimInfoToString(RedisModuleClusterSlotMigrationTrimInfo *info, uint64_t sub) { - RedisModule_Assert(info); - char buf[1024] = {0}; - - if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_TRIM_BACKGROUND) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-trim-background, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_TRIM_STARTED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-trim-started, "); - else if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_TRIM_COMPLETED) - snprintf(buf, sizeof(buf), "sub: cluster-slot-migration-trim-completed, "); - else { - RedisModule_Assert(0); - } - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "slots:"); - for (int i = 0; i < info->slots->num_ranges; i++) { - RedisModuleSlotRange *sr = &info->slots->ranges[i]; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%d-%d", sr->start, sr->end); - if (i != info->slots->num_ranges - 1) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ","); - } - return RedisModule_Strdup(buf); -} - -static void testReplicatingOutsideSlotRange(RedisModuleCtx *ctx, RedisModuleClusterSlotMigrationInfo *info) { - int slot = 0; - while (slot >= 0 && slot <= 16383) { - if (!slotRangeArrayContains(info->slots, slot)) { - break; - } - slot++; - } - char buf[128] = {0}; - const char *prefix = RedisModule_ClusterCanonicalKeyNameInSlot(slot); - snprintf(buf, sizeof(buf), "{%s}%s", prefix, "modulekey"); - errno = 0; - int ret = RedisModule_ClusterPropagateForSlotMigration(ctx, "SET", "cc", buf, "value"); - RedisModule_Assert(ret == REDISMODULE_ERR); - RedisModule_Assert(errno == ERANGE); -} - -static void testReplicatingCrossslotCommand(RedisModuleCtx *ctx) { - errno = 0; - int ret = RedisModule_ClusterPropagateForSlotMigration(ctx, "MSET", "cccccc", "key1", "val1", "key2", "val2", "key3", "val3"); - RedisModule_Assert(ret == REDISMODULE_ERR); - RedisModule_Assert(errno == ENOTSUP); -} - -static void testReplicatingUnknownCommand(RedisModuleCtx *ctx) { - errno = 0; - int ret = RedisModule_ClusterPropagateForSlotMigration(ctx, "unknowncommand", ""); - RedisModule_Assert(ret == REDISMODULE_ERR); - RedisModule_Assert(errno == ENOENT); -} - -static void testNonFatalScenarios(RedisModuleCtx *ctx, RedisModuleClusterSlotMigrationInfo *info) { - testReplicatingOutsideSlotRange(ctx, info); - testReplicatingCrossslotCommand(ctx); - testReplicatingUnknownCommand(ctx); -} - -int disableTrimCmd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - disableTrimFlag = 1; - /* Only disable when MIGRATE_COMPLETED for simulating recommended usage. */ - // RedisModule_ClusterDisableTrim(ctx) - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -int enableTrimCmd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - disableTrimFlag = 0; - RedisModule_Assert(RedisModule_ClusterEnableTrim(ctx) == REDISMODULE_OK); - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -int trimInProgressCmd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - uint64_t flags = RedisModule_GetContextFlags(ctx); - RedisModule_ReplyWithLongLong(ctx, !!(flags & REDISMODULE_CTX_FLAGS_TRIM_IN_PROGRESS)); - return REDISMODULE_OK; -} - -void clusterEventCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data) { - REDISMODULE_NOT_USED(ctx); - int ret; - - RedisModule_Assert(RedisModule_IsSubEventSupported(e, sub)); - - if (e.id == REDISMODULE_EVENT_CLUSTER_SLOT_MIGRATION) { - RedisModuleClusterSlotMigrationInfo *info = data; - - if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_MIGRATE_MODULE_PROPAGATE) { - /* Test some non-fatal scenarios. */ - testNonFatalScenarios(ctx, info); - - if (replicateModuleCommand == 0) return; - - /* Replicate a keyless command. */ - ret = RedisModule_ClusterPropagateForSlotMigration(ctx, "asm.keyless_cmd", ""); - RedisModule_Assert(ret == REDISMODULE_OK); - - /* Propagate configured key and value. */ - ret = RedisModule_ClusterPropagateForSlotMigration(ctx, "SET", "ss", moduleCommandKeyName, moduleCommandKeyVal); - RedisModule_Assert(ret == REDISMODULE_OK); - } else { - /* Log the event. */ - if (numClusterEvents >= MAX_EVENTS) return; - clusterEventLog[numClusterEvents++] = clusterAsmInfoToString(info, sub); - - if (sub == REDISMODULE_SUBEVENT_CLUSTER_SLOT_MIGRATION_MIGRATE_COMPLETED) { - /* If users ask to disable trim, we disable trim. */ - if (disableTrimFlag) { - RedisModule_Assert(RedisModule_ClusterDisableTrim(ctx) == REDISMODULE_OK); - } - } - } - } -} - -int getPendingTrimKeyCmd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 2) { - RedisModule_ReplyWithError(ctx, "ERR wrong number of arguments"); - return REDISMODULE_ERR; - } - RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], - REDISMODULE_READ | REDISMODULE_OPEN_KEY_ACCESS_TRIMMED); - if (!key) { - RedisModule_ReplyWithNull(ctx); - return REDISMODULE_OK; - } - if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_STRING) { - RedisModule_ReplyWithError(ctx, "key is not a string"); - return REDISMODULE_ERR; - } - size_t len; - const char *value = RedisModule_StringDMA(key, &len, 0); - RedisModule_ReplyWithStringBuffer(ctx, value, len); - RedisModule_CloseKey(key); - return REDISMODULE_OK; -} - -void clusterTrimEventCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data) { - REDISMODULE_NOT_USED(ctx); - - RedisModule_Assert(RedisModule_IsSubEventSupported(e, sub)); - - if (e.id == REDISMODULE_EVENT_CLUSTER_SLOT_MIGRATION_TRIM) { - /* Log the event. */ - if (numClusterTrimEvents >= MAX_EVENTS) return; - RedisModuleClusterSlotMigrationTrimInfo *info = data; - clusterTrimEventLog[numClusterTrimEvents++] = clusterTrimInfoToString(info, sub); - } -} - -static int keyspaceNotificationTrimmedCallback(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) { - REDISMODULE_NOT_USED(ctx); - - RedisModule_Assert(type == REDISMODULE_NOTIFY_KEY_TRIMMED); - RedisModule_Assert(strcmp(event, "key_trimmed") == 0); - - if (numClusterTrimEvents >= MAX_EVENTS) return REDISMODULE_OK; - - /* Log the trimmed key event. */ - size_t len; - const char *key_str = RedisModule_StringPtrLen(key, &len); - - char buf[1024] = {0}; - snprintf(buf, sizeof(buf), "keyspace: key_trimmed, key: %s", key_str); - - clusterTrimEventLog[numClusterTrimEvents++] = RedisModule_Strdup(buf); - return REDISMODULE_OK; -} - -/* ASM.PARENT SET key value (just proxy to Redis SET) */ -static int asmParentSet(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 4) return RedisModule_WrongArity(ctx); - RedisModuleCallReply *reply = RedisModule_Call(ctx, "SET", "ss", argv[2], argv[3]); - if (!reply) return RedisModule_ReplyWithError(ctx, "ERR internal"); - RedisModule_ReplyWithCallReply(ctx, reply); - RedisModule_FreeCallReply(reply); - RedisModule_ReplicateVerbatim(ctx); - return REDISMODULE_OK; -} - -/* Clear both the cluster and trim event logs. */ -int clearEventLog(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - for (int i = 0; i < numClusterEvents; i++) - RedisModule_Free((void *)clusterEventLog[i]); - numClusterEvents = 0; - - for (int i = 0; i < numClusterTrimEvents; i++) - RedisModule_Free((void *)clusterTrimEventLog[i]); - numClusterTrimEvents = 0; - - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -/* Reply with the cluster event log. */ -int getClusterEventLog(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - RedisModule_ReplyWithArray(ctx, numClusterEvents); - for (int i = 0; i < numClusterEvents; i++) - RedisModule_ReplyWithStringBuffer(ctx, clusterEventLog[i], strlen(clusterEventLog[i])); - return REDISMODULE_OK; -} - -/* Reply with the cluster trim event log. */ -int getClusterTrimEventLog(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - RedisModule_ReplyWithArray(ctx, numClusterTrimEvents); - for (int i = 0; i < numClusterTrimEvents; i++) - RedisModule_ReplyWithStringBuffer(ctx, clusterTrimEventLog[i], strlen(clusterTrimEventLog[i])); - return REDISMODULE_OK; -} - -/* A keyless command to test module command replication. */ -int moduledata = 0; -int keylessCmd(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - moduledata++; - RedisModule_ReplyWithLongLong(ctx, moduledata); - return REDISMODULE_OK; -} -int readkeylessCmdVal(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - RedisModule_ReplyWithLongLong(ctx, moduledata); - return REDISMODULE_OK; -} - -int subscribeTrimmedEvent(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - if (argc != 2) - return RedisModule_WrongArity(ctx); - - long long subscribe = 0; - if (RedisModule_StringToLongLong(argv[1], &subscribe) != REDISMODULE_OK) { - RedisModule_ReplyWithError(ctx, "ERR subscribe value"); - return REDISMODULE_OK; - } - - if (subscribe) { - /* Unsubscribe first to avoid duplicate subscription. */ - RedisModule_UnsubscribeFromKeyspaceEvents(ctx, REDISMODULE_NOTIFY_KEY_TRIMMED, keyspaceNotificationTrimmedCallback); - int ret = RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_KEY_TRIMMED, keyspaceNotificationTrimmedCallback); - RedisModule_Assert(ret == REDISMODULE_OK); - } else { - int ret = RedisModule_UnsubscribeFromKeyspaceEvents(ctx, REDISMODULE_NOTIFY_KEY_TRIMMED, keyspaceNotificationTrimmedCallback); - RedisModule_Assert(ret == REDISMODULE_OK); - } - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -void keyEventCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data) { - REDISMODULE_NOT_USED(ctx); - REDISMODULE_NOT_USED(e); - - if (sub == REDISMODULE_SUBEVENT_KEY_DELETED) { - RedisModuleKeyInfoV1 *ei = data; - RedisModuleKey *kp = ei->key; - RedisModuleString *key = (RedisModuleString *) RedisModule_GetKeyNameFromModuleKey(kp); - size_t keylen; - const char *keyname = RedisModule_StringPtrLen(key, &keylen); - - /* Verify value can be read. It will be used to verify key's value can - * be read in a trim callback. */ - size_t valuelen = 0; - const char *value = ""; - RedisModuleKey *mk = RedisModule_OpenKey(ctx, key, REDISMODULE_READ); - if (RedisModule_KeyType(mk) == REDISMODULE_KEYTYPE_STRING) { - value = RedisModule_StringDMA(mk, &valuelen, 0); - } - RedisModule_CloseKey(mk); - - char buf[1024] = {0}; - snprintf(buf, sizeof(buf), "keyevent: key: %.*s, value: %.*s", (int) keylen, keyname, (int)valuelen, value); - - if (lastDeletedKeyLog) RedisModule_Free((void *)lastDeletedKeyLog); - lastDeletedKeyLog = RedisModule_Strdup(buf); - } -} - -int getLastDeletedKey(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - if (lastDeletedKeyLog) { - RedisModule_ReplyWithStringBuffer(ctx, lastDeletedKeyLog, strlen(lastDeletedKeyLog)); - } else { - RedisModule_ReplyWithNull(ctx); - } - return REDISMODULE_OK; -} - -int asmGetCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(ctx); - - if (argc != 2) return RedisModule_WrongArity(ctx); - RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ); - if (key == NULL) { - RedisModule_ReplyWithNull(ctx); - return REDISMODULE_OK; - } - - RedisModule_Assert(RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_STRING); - size_t len; - const char *value = RedisModule_StringDMA(key, &len, 0); - RedisModule_ReplyWithStringBuffer(ctx, value, len); - RedisModule_CloseKey(key); - - return REDISMODULE_OK; -} - -int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - if (RedisModule_Init(ctx, "asm", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.cluster_can_access_keys_in_slot", testClusterCanAccessKeysInSlot, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.clear_event_log", clearEventLog, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.get_cluster_event_log", getClusterEventLog, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.get_cluster_trim_event_log", getClusterTrimEventLog, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.keyless_cmd", keylessCmd, "write", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.disable_trim", disableTrimCmd, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.enable_trim", enableTrimCmd, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.read_pending_trim_key", getPendingTrimKeyCmd, "readonly", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.trim_in_progress", trimInProgressCmd, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.read_keyless_cmd_val", readkeylessCmdVal, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.sanity", sanity, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.subscribe_trimmed_event", subscribeTrimmedEvent, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.replicate_module_command", replicate_module_command, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.lpush_replicate_crossslot_command", lpush_and_replicate_crossslot_command, "write", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.cluster_get_local_slot_ranges", testClusterGetLocalSlotRanges, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.get_last_deleted_key", getLastDeletedKey, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.get", asmGetCommand, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx, "asm.parent", NULL, "", 0, 0, 0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - RedisModuleCommand *parent = RedisModule_GetCommand(ctx, "asm.parent"); - if (!parent) return REDISMODULE_ERR; - - /* Subcommand: ASM.PARENT SET (write) */ - if (RedisModule_CreateSubcommand(parent, "set", asmParentSet, "write fast", 2, 2, 1) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_ClusterSlotMigration, clusterEventCallback) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_ClusterSlotMigrationTrim, clusterTrimEventCallback) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_KEY_TRIMMED, keyspaceNotificationTrimmedCallback) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_Key, keyEventCallback) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - return REDISMODULE_OK; -} |
