hmartiro / redox

Modern, asynchronous, and wicked fast C++11 client for Redis
Apache License 2.0
388 stars 101 forks source link

Reconnection #21

Open Cylix opened 9 years ago

Cylix commented 9 years ago

Hi

I'd like to know how to handle reconnection with your library?

I'm currenlty setting the connection handler and I'd like to try to reconnect to the redis server in case of unexpected disconnection.

For that, I've tried to first call redox::disconnect() and then redox::connect, but the program abort in the redox::connect because the event loop thread has not been joined (when the event_loop thread is reset in the redox::connect, the previous thread is destroyed without having being joined before).

But even if I join the thread in the disconnect method, my program crashes with a segfault. Here is a backtrace:

[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace:66): segmentation fault
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 1 ecctv_server 0x000000010829e670 sigcrash_handler(int) + 16
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 2 libsystem_platform.dylib 0x00007fff87f34f1a _sigtramp + 26
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 3 ??? 0x0a007fd46af0cdc8 0x0 + 720716490683239880
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 4 libc++.1.dylib 0x00007fff83bfbb6f _ZNSt3__15mutex4lockEv + 9
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 5 libredox.0.dylib 0x000000010871cf4f redox::Command<redisReply*>::free() + 31
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 6 libredox.0.dylib 0x000000010872b069 redox::Subscriber::stop() + 777
[ERR ] [2015-07-10 - 11:19:17] (ecctv_server::log_backtrace_line:56): 7 libredox.0.dylib 0x000000010872ad4e redox::Subscriber::disconnect() + 14

What shall we do if we want to reconnect? Build a new Redox object? Or calling specific methods that does the work?

Cylix commented 9 years ago

I've found a temporary solution.

Each time a disconnection happens, I build a redox object in order to try to establish a new connection. In code, in gives me something like:

std::shared_ptr<redox::Redox> conn = std::make_shared<redox::Redox>(/* some configuration */);
conn->connect("127.0.0.1", 6379, state_changed_callback);

Then, when a disconnection is detected and state_changed_callback is called, I simply make:

conn->disconnect();
conn = std::make_shared<redox::Redox>(/* some configuration */);
conn->connect("127.0.0.1", 6379, state_changed_callback);

This works like a charm with the redox client. However, it is broken for the redox subscriber client.

If I call redox::Subscriber::disconnect, it results in a segfault with a backtrace similar to the one posted in the first post. So I only rebuild a new subscriber instance without calling disconnect on the old one each time a subscriber is disconnected.

This is a quite bad situation concerning the subscriber since nothing is freed in the redox::Subscriber destructor (unlike in the redox client), so it may be a possible source of memory leaks.

hmartiro commented 9 years ago

Hi Cylix, I agree that disconnection/reconnection is the biggest outstanding issue for Redox. I've been frustrated by the strange things hiredis tends to do. Definitely would like to take another smack at it when I get a chance.

gunzino commented 9 years ago

Hello,

Is there some fixes already for that problem ? I would like to implement Redox to my production app.

Cylix commented 9 years ago

I currently use a simple solution in my application (it is working in production). If I want to reconnect, I simply close the previous connection and try to connect with a new redox client object.

Not really elegant but it works.

gunzino commented 9 years ago

Okay thank you, I've seen your library but probably I will use this one. Is it possible to check if Redox is connected to the redis before calling some command ?

Or I should just setup the disconnection hanlder.

gunzino commented 9 years ago

Heya, I've setup the handler, everything works but now also experiencing the problem with the subscribe. I just have to create new object without disonnection.