Skip to content

Commit f3e5bf6

Browse files
committed
fix - Ping Redis every 10 seconds
1 parent f1bddc1 commit f3e5bf6

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

megaphone.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include "hiredis/async.h"
77
#include "hiredis/adapters/libuv.h"
88

9-
/* Todo: send redis PING every 10 seconds */
10-
119
#include "App.h"
1210

1311
/* We use libuv to share the same event loop across hiredis and uSockets */
@@ -22,6 +20,9 @@ const char *redisHostname;
2220
int redisPort;
2321
const char *redisTopic;
2422

23+
/* We use this to ping Redis */
24+
uv_timer_t pingTimer;
25+
2526
void onMessage(redisAsyncContext *c, void *reply, void *privdata);
2627

2728
/* Connect to Redis server, manages reconnect by calling itself when needed */
@@ -56,6 +57,9 @@ redisAsyncContext *connectToRedis(uWS::App *app) {
5657
});
5758

5859
redisAsyncSetDisconnectCallback(c, [](const redisAsyncContext *c, int status) {
60+
/* We are no longer connected to Redis, so stop pinging it */
61+
pingTimer.data = nullptr;
62+
5963
if (status != REDIS_OK) {
6064
printf("Lost connection to Redis: %s\n", c->errstr);
6165

@@ -87,6 +91,8 @@ void onMessage(redisAsyncContext *c, void *reply, void *privdata) {
8791
return;
8892
}
8993

94+
/* PONG responses are discarded by hiredis even though they technically reach us */
95+
9096
if (r->type == REDIS_REPLY_ARRAY) {
9197
/* We always expect action, topic, message */
9298
if (r->elements == 3) {
@@ -104,6 +110,7 @@ void onMessage(redisAsyncContext *c, void *reply, void *privdata) {
104110
printf("We are connected and subscribed to Redis now\n");
105111

106112
/* Start a timer sending Pings to Redis */
113+
pingTimer.data = c;
107114
}
108115
}
109116
}
@@ -152,6 +159,18 @@ int main() {
152159
uWS::Loop::get(uv_default_loop());
153160
uWS::App app;
154161

162+
/* Start a timer sending pings to Redis every 10 seconds */
163+
uv_timer_init(uv_default_loop(), &pingTimer);
164+
pingTimer.data = nullptr;
165+
uv_timer_start(&pingTimer, [](uv_timer_t *t) {
166+
/* We store currently connected Redis context in user data */
167+
redisAsyncContext *c = (redisAsyncContext *) t->data;
168+
169+
/* Redis does respond with a PONG but hiredis bugs discard it so the callback is never called.
170+
* For us this doesn't matter as we only want to send something to trigger errors on the socket if so */
171+
redisAsyncCommand((redisAsyncContext *) c, onMessage, c->data, "PING");
172+
}, 10000, 10000);
173+
155174
/* Connect to Redis, this will automatically keep reconnecting once disconnected */
156175
connectToRedis(&app);
157176

0 commit comments

Comments
 (0)