mirror of
https://github.com/fluencelabs/redis
synced 2025-03-20 17:40:50 +00:00
Modules Cluster API: sending / receiving API first implementation.
This commit is contained in:
parent
0701cad3de
commit
b4dc782e4e
78
src/module.c
78
src/module.c
@ -3812,23 +3812,91 @@ void moduleUnsubscribeNotifications(RedisModule *module) {
|
|||||||
* Modules Cluster API
|
* Modules Cluster API
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The Cluster message callback function pointer type. */
|
||||||
typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
|
typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
|
||||||
|
|
||||||
/* This structure identifies a registered caller: it must match a given module
|
/* This structure identifies a registered caller: it must match a given module
|
||||||
* ID, for a given message type. The callback function is just the function
|
* ID, for a given message type. The callback function is just the function
|
||||||
* that was registered as receiver. */
|
* that was registered as receiver. */
|
||||||
struct moduleClusterReceiver {
|
typedef struct moduleClusterReceiver {
|
||||||
uint64_t module_id;
|
uint64_t module_id;
|
||||||
uint8_t msg_type;
|
|
||||||
RedisModuleClusterMessageReceiver callback;
|
RedisModuleClusterMessageReceiver callback;
|
||||||
|
struct RedisModule *module;
|
||||||
struct moduleClusterReceiver *next;
|
struct moduleClusterReceiver *next;
|
||||||
};
|
} moduleClusterReceiver;
|
||||||
|
|
||||||
/* We have an array of message types: each bucket is a linked list of
|
/* We have an array of message types: each bucket is a linked list of
|
||||||
* configured receivers. */
|
* configured receivers. */
|
||||||
static struct moduleClusterReceiver *clusterReceivers[UINT8_MAX];
|
static moduleClusterReceiver *clusterReceivers[UINT8_MAX];
|
||||||
|
|
||||||
|
/* Dispatch the message to the right module receiver. */
|
||||||
void moduleCallClusterReceivers(char *sender_id, uint64_t module_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
void moduleCallClusterReceivers(char *sender_id, uint64_t module_id, uint8_t type, const unsigned char *payload, uint32_t len) {
|
||||||
|
moduleClusterReceiver *r = clusterReceivers[type];
|
||||||
|
while(r) {
|
||||||
|
if (r->module_id == module_id) {
|
||||||
|
RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
|
||||||
|
ctx.module = r->module;
|
||||||
|
r->callback(&ctx,sender_id,type,payload,len);
|
||||||
|
moduleFreeContext(&ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = r->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register a callback receiver for cluster messages of type 'type'. If there
|
||||||
|
* was already a registered callback, this will replace the callback function
|
||||||
|
* with the one provided, otherwise if the callback is set to NULL and there
|
||||||
|
* is already a callback for this function, the callback is unregistered
|
||||||
|
* (so this API call is also used in order to delete the receiver). */
|
||||||
|
void RM_RegisterClusterMessageReceiver(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback) {
|
||||||
|
uint64_t module_id = moduleTypeEncodeId(ctx->module->name,0);
|
||||||
|
moduleClusterReceiver *r = clusterReceivers[type], *prev = NULL;
|
||||||
|
while(r) {
|
||||||
|
if (r->module_id == module_id) {
|
||||||
|
/* Found! Set or delete. */
|
||||||
|
if (callback) {
|
||||||
|
r->callback = callback;
|
||||||
|
} else {
|
||||||
|
/* Delete the receiver entry if the user is setting
|
||||||
|
* it to NULL. Just unlink the receiver node from the
|
||||||
|
* linked list. */
|
||||||
|
if (prev)
|
||||||
|
prev->next = r->next;
|
||||||
|
else
|
||||||
|
clusterReceivers[type]->next = r->next;
|
||||||
|
zfree(r);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev = r;
|
||||||
|
r = r->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found, let's add it. */
|
||||||
|
if (callback) {
|
||||||
|
r = zmalloc(sizeof(*r));
|
||||||
|
r->module_id = module_id;
|
||||||
|
r->module = ctx->module;
|
||||||
|
r->callback = callback;
|
||||||
|
r->next = clusterReceivers[type];
|
||||||
|
clusterReceivers[type] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a message to all the nodes in the cluster if `target` is NULL, otherwise
|
||||||
|
* at the specified target, which is a REDISMODULE_NODE_ID_LEN bytes node ID, as
|
||||||
|
* returned by the receiver callback or by the nodes iteration functions.
|
||||||
|
*
|
||||||
|
* The function returns REDISMODULE_OK if the message was successfully sent,
|
||||||
|
* otherwise if the node is not connected or such node ID does not map to any
|
||||||
|
* known cluster node, REDISMODULE_ERR is returned. */
|
||||||
|
int RM_SendClusterMessage(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len) {
|
||||||
|
uint64_t module_id = moduleTypeEncodeId(ctx->module->name,0);
|
||||||
|
if (clusterSendModuleMessageToTarget(target_id,module_id,type,msg,len) == C_OK)
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
else
|
||||||
|
return REDISMODULE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
@ -4210,4 +4278,6 @@ void moduleRegisterCoreAPI(void) {
|
|||||||
REGISTER_API(DigestAddLongLong);
|
REGISTER_API(DigestAddLongLong);
|
||||||
REGISTER_API(DigestEndSequence);
|
REGISTER_API(DigestEndSequence);
|
||||||
REGISTER_API(SubscribeToKeyspaceEvents);
|
REGISTER_API(SubscribeToKeyspaceEvents);
|
||||||
|
REGISTER_API(RegisterClusterMessageReceiver);
|
||||||
|
REGISTER_API(SendClusterMessage);
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,9 @@
|
|||||||
#define REDISMODULE_POSITIVE_INFINITE (1.0/0.0)
|
#define REDISMODULE_POSITIVE_INFINITE (1.0/0.0)
|
||||||
#define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0)
|
#define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0)
|
||||||
|
|
||||||
|
/* Cluster API defines. */
|
||||||
|
#define REDISMODULE_NODE_ID_LEN 40
|
||||||
|
|
||||||
#define REDISMODULE_NOT_USED(V) ((void) V)
|
#define REDISMODULE_NOT_USED(V) ((void) V)
|
||||||
|
|
||||||
/* ------------------------- End of common defines ------------------------ */
|
/* ------------------------- End of common defines ------------------------ */
|
||||||
@ -123,7 +126,6 @@ typedef struct RedisModuleDigest RedisModuleDigest;
|
|||||||
typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
|
typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
|
||||||
|
|
||||||
typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
|
typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
|
||||||
|
|
||||||
typedef int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
|
typedef int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
|
||||||
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
|
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
|
||||||
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
|
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
|
||||||
@ -131,6 +133,7 @@ typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString
|
|||||||
typedef size_t (*RedisModuleTypeMemUsageFunc)(const void *value);
|
typedef size_t (*RedisModuleTypeMemUsageFunc)(const void *value);
|
||||||
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
|
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
|
||||||
typedef void (*RedisModuleTypeFreeFunc)(void *value);
|
typedef void (*RedisModuleTypeFreeFunc)(void *value);
|
||||||
|
typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
|
||||||
|
|
||||||
#define REDISMODULE_TYPE_METHOD_VERSION 1
|
#define REDISMODULE_TYPE_METHOD_VERSION 1
|
||||||
typedef struct RedisModuleTypeMethods {
|
typedef struct RedisModuleTypeMethods {
|
||||||
@ -251,6 +254,7 @@ long long REDISMODULE_API_FUNC(RedisModule_Milliseconds)(void);
|
|||||||
void REDISMODULE_API_FUNC(RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len);
|
void REDISMODULE_API_FUNC(RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len);
|
||||||
void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele);
|
void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele);
|
||||||
void REDISMODULE_API_FUNC(RedisModule_DigestEndSequence)(RedisModuleDigest *md);
|
void REDISMODULE_API_FUNC(RedisModule_DigestEndSequence)(RedisModuleDigest *md);
|
||||||
|
int REDISMODULE_API(RedisModule_SendClusterMessage)(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len);
|
||||||
|
|
||||||
/* Experimental APIs */
|
/* Experimental APIs */
|
||||||
#ifdef REDISMODULE_EXPERIMENTAL_API
|
#ifdef REDISMODULE_EXPERIMENTAL_API
|
||||||
@ -265,6 +269,7 @@ void REDISMODULE_API_FUNC(RedisModule_FreeThreadSafeContext)(RedisModuleCtx *ctx
|
|||||||
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextLock)(RedisModuleCtx *ctx);
|
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextLock)(RedisModuleCtx *ctx);
|
||||||
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextUnlock)(RedisModuleCtx *ctx);
|
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextUnlock)(RedisModuleCtx *ctx);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_SubscribeToKeyspaceEvents)(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc cb);
|
int REDISMODULE_API_FUNC(RedisModule_SubscribeToKeyspaceEvents)(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc cb);
|
||||||
|
void REDISMODULE_API_FUNC(RedisModule_RegisterClusterMessageReceiver)(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -375,6 +380,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
|
|||||||
REDISMODULE_GET_API(DigestAddStringBuffer);
|
REDISMODULE_GET_API(DigestAddStringBuffer);
|
||||||
REDISMODULE_GET_API(DigestAddLongLong);
|
REDISMODULE_GET_API(DigestAddLongLong);
|
||||||
REDISMODULE_GET_API(DigestEndSequence);
|
REDISMODULE_GET_API(DigestEndSequence);
|
||||||
|
REDISMODULE_GET_API(SendClusterMessage);
|
||||||
|
|
||||||
#ifdef REDISMODULE_EXPERIMENTAL_API
|
#ifdef REDISMODULE_EXPERIMENTAL_API
|
||||||
REDISMODULE_GET_API(GetThreadSafeContext);
|
REDISMODULE_GET_API(GetThreadSafeContext);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user