Is it possible to send a message out periodically, like a HB, using the timer? The reply does not go out to the redis client connected.

Line number 10 and Line number 5


1. void timerHandler(RedisModuleCtx *ctx, void *data) {
2.  REDISMODULE_NOT_USED(ctx);
3.  REDISMODULE_NOT_USED(data);
4.     //build the message -reply
5.     RedisModule_ReplyWithString(ctx, reply);
6. }
7. 
8. int MyCmd_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
9.  if (argc != 2) return RedisModule_WrongArity(ctx);
10.     RedisModule_CreateTimer(ctx, 1000, timerHandler, ctx);
11.         return REDISMODULE_OK;
12. }
13. 
14. int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
15.     REDISMODULE_NOT_USED(argv);
16.     REDISMODULE_NOT_USED(argc);
17.     if (RedisModule_Init(ctx, "my_cmd", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
18.               return RedisModule_ReplyWithError(ctx, "-ERR Can't init mycmd module");
19. 
20.     if (RedisModule_CreateCommand(ctx, "my_cmd.cmd", MyCmd_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
21.         return RedisModule_ReplyWithError(ctx, "-ERR Can't init mycmd command");
22.     return REDISMODULE_OK;
22. }

Comment From: chenyang8094

An easy way is that you can send pubsub (use RedisModule_PublishMessage) in timer.

If you insist on your scheme, consider using a block client.

Comment From: nsharmanahellc

@chenyang8094 thanks, but who will subscribe and who will get the message? please note my client is simple TCP and it does not subscribe to a channel.

The block client wont work as during the block I cannot respond a client command as the response to it will be kept with the blocked clients list.

Could I get the client context in the timer so I can reply to the client like the command execution in the module will help or any other internal API? The time is being kicked off rightly but ctx is not the client context.

Comment From: oranagra

AFAIK, other than PUBSUB, at the moment we only allow sending messages to clients as part of a reply to a command they issued. so you could block the client and later send a reply. we do have a desire to add some mechanism for RESP3, push messages, but no specific design for that yet.

Comment From: nsharmanahellc

@oranagra and @chenyang8094 - thanks guys for your quick responses. so I had put a work around and managed to get the push messages from the module to the client. The only issue I have is related to the state. For example- when preparing the message to be sent, I may have a client disconnected. Is there any way to hold the state for a given client during the push message handling in the timer callback?

Comment From: chenyang8094

You can pass a block client context through the data parameter of timerHandler. For details, please refer to the code here. I think it can solve your problem.

Comment From: oranagra

@nsharmanahellc are you trying to implement some generic mechanism for modules to send push messages to random clients? if you are, and you end up with something sane, maybe you can make a PR (or publish the API design).

Comment From: nsharmanahellc

@oranagra, yes but I may take a week as I need to test it more and take permission from my employer. Is there any document that guide for PR? Thanks

Comment From: oranagra

maybe there's something in the README.md, but it might be outdated.

Comment From: tzongw

Hey, I am doing some similar things, hope this project can help. redis-timer