summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/src/modules/hellocluster.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/src/modules/hellocluster.c')
-rw-r--r--examples/redis-unstable/src/modules/hellocluster.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/examples/redis-unstable/src/modules/hellocluster.c b/examples/redis-unstable/src/modules/hellocluster.c
new file mode 100644
index 0000000..38d7e1f
--- /dev/null
+++ b/examples/redis-unstable/src/modules/hellocluster.c
@@ -0,0 +1,98 @@
+/* Helloworld cluster -- A ping/pong cluster API example.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018-Present, Redis Ltd.
+ * All rights reserved.
+ *
+ * Licensed under your choice of (a) the Redis Source Available License 2.0
+ * (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
+ * GNU Affero General Public License v3 (AGPLv3).
+ */
+
+#include "../redismodule.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#define MSGTYPE_PING 1
+#define MSGTYPE_PONG 2
+
+/* HELLOCLUSTER.PINGALL */
+int PingallCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
+
+ RedisModule_SendClusterMessage(ctx,NULL,MSGTYPE_PING,"Hey",3);
+ return RedisModule_ReplyWithSimpleString(ctx, "OK");
+}
+
+/* HELLOCLUSTER.LIST */
+int ListCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
+
+ size_t numnodes;
+ char **ids = RedisModule_GetClusterNodesList(ctx,&numnodes);
+ if (ids == NULL) {
+ return RedisModule_ReplyWithError(ctx,"Cluster not enabled");
+ }
+
+ RedisModule_ReplyWithArray(ctx,numnodes);
+ for (size_t j = 0; j < numnodes; j++) {
+ int port;
+ RedisModule_GetClusterNodeInfo(ctx,ids[j],NULL,NULL,&port,NULL);
+ RedisModule_ReplyWithArray(ctx,2);
+ RedisModule_ReplyWithStringBuffer(ctx,ids[j],REDISMODULE_NODE_ID_LEN);
+ RedisModule_ReplyWithLongLong(ctx,port);
+ }
+ RedisModule_FreeClusterNodesList(ids);
+ return REDISMODULE_OK;
+}
+
+/* Callback for message MSGTYPE_PING */
+void PingReceiver(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
+ RedisModule_Log(ctx,"notice","PING (type %d) RECEIVED from %.*s: '%.*s'",
+ type,REDISMODULE_NODE_ID_LEN,sender_id,(int)len, payload);
+ RedisModule_SendClusterMessage(ctx,NULL,MSGTYPE_PONG,"Ohi!",4);
+ RedisModuleCallReply *reply = RedisModule_Call(ctx, "INCR", "c", "pings_received");
+ RedisModule_FreeCallReply(reply);
+}
+
+/* Callback for message MSGTYPE_PONG. */
+void PongReceiver(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) {
+ RedisModule_Log(ctx,"notice","PONG (type %d) RECEIVED from %.*s: '%.*s'",
+ type,REDISMODULE_NODE_ID_LEN,sender_id,(int)len, payload);
+}
+
+/* This function must be present on each Redis module. It is used in order to
+ * register the commands into the Redis server. */
+int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
+
+ if (RedisModule_Init(ctx,"hellocluster",1,REDISMODULE_APIVER_1)
+ == REDISMODULE_ERR) return REDISMODULE_ERR;
+
+ if (RedisModule_CreateCommand(ctx,"hellocluster.pingall",
+ PingallCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
+ if (RedisModule_CreateCommand(ctx,"hellocluster.list",
+ ListCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
+ /* Disable Redis Cluster sharding and redirections. This way every node
+ * will be able to access every possible key, regardless of the hash slot.
+ * This way the PING message handler will be able to increment a specific
+ * variable. Normally you do that in order for the distributed system
+ * you create as a module to have total freedom in the keyspace
+ * manipulation. */
+ RedisModule_SetClusterFlags(ctx,REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION);
+
+ /* Register our handlers for different message types. */
+ RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PING,PingReceiver);
+ RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PONG,PongReceiver);
+ return REDISMODULE_OK;
+}