Commit a8a81ee77720903528da0bdeda85bd6f39c0182b
1 parent
b5d5ea9a
Improved connect/disconnect management
Consolidated user callbacks into one, improved some logic.
Showing
11 changed files
with
39 additions
and
45 deletions
CMakeLists.txt
| @@ -32,11 +32,11 @@ set(LIB_ALL ${LIB_REDIS}) | @@ -32,11 +32,11 @@ set(LIB_ALL ${LIB_REDIS}) | ||
| 32 | add_executable(basic examples/basic.cpp ${SRC_ALL}) | 32 | add_executable(basic examples/basic.cpp ${SRC_ALL}) |
| 33 | target_link_libraries(basic ${LIB_REDIS}) | 33 | target_link_libraries(basic ${LIB_REDIS}) |
| 34 | 34 | ||
| 35 | -#add_executable(basic_threaded examples/basic_threaded.cpp ${SRC_ALL}) | ||
| 36 | -#target_link_libraries(basic_threaded ${LIB_REDIS}) | 35 | +add_executable(basic_threaded examples/basic_threaded.cpp ${SRC_ALL}) |
| 36 | +target_link_libraries(basic_threaded ${LIB_REDIS}) | ||
| 37 | 37 | ||
| 38 | -#add_executable(lpush_benchmark examples/lpush_benchmark.cpp ${SRC_ALL}) | ||
| 39 | -#target_link_libraries(lpush_benchmark ${LIB_REDIS}) | 38 | +add_executable(lpush_benchmark examples/lpush_benchmark.cpp ${SRC_ALL}) |
| 39 | +target_link_libraries(lpush_benchmark ${LIB_REDIS}) | ||
| 40 | 40 | ||
| 41 | add_executable(speed_test_async examples/speed_test_async.cpp ${SRC_ALL}) | 41 | add_executable(speed_test_async examples/speed_test_async.cpp ${SRC_ALL}) |
| 42 | target_link_libraries(speed_test_async ${LIB_REDIS}) | 42 | target_link_libraries(speed_test_async ${LIB_REDIS}) |
| @@ -44,14 +44,14 @@ target_link_libraries(speed_test_async ${LIB_REDIS}) | @@ -44,14 +44,14 @@ target_link_libraries(speed_test_async ${LIB_REDIS}) | ||
| 44 | add_executable(speed_test_sync examples/speed_test_sync.cpp ${SRC_ALL}) | 44 | add_executable(speed_test_sync examples/speed_test_sync.cpp ${SRC_ALL}) |
| 45 | target_link_libraries(speed_test_sync ${LIB_REDIS}) | 45 | target_link_libraries(speed_test_sync ${LIB_REDIS}) |
| 46 | 46 | ||
| 47 | -#add_executable(speed_test_async_multi examples/speed_test_async_multi.cpp ${SRC_ALL}) | ||
| 48 | -#target_link_libraries(speed_test_async_multi ${LIB_REDIS}) | 47 | +add_executable(speed_test_async_multi examples/speed_test_async_multi.cpp ${SRC_ALL}) |
| 48 | +target_link_libraries(speed_test_async_multi ${LIB_REDIS}) | ||
| 49 | 49 | ||
| 50 | -#add_executable(data_types examples/data_types.cpp ${SRC_ALL}) | ||
| 51 | -#target_link_libraries(data_types ${LIB_REDIS}) | 50 | +add_executable(data_types examples/data_types.cpp ${SRC_ALL}) |
| 51 | +target_link_libraries(data_types ${LIB_REDIS}) | ||
| 52 | 52 | ||
| 53 | -#add_executable(string_v_char examples/string_vs_charp.cpp ${SRC_ALL}) | ||
| 54 | -#target_link_libraries(string_v_char ${LIB_REDIS}) | 53 | +add_executable(string_v_char examples/string_vs_charp.cpp ${SRC_ALL}) |
| 54 | +target_link_libraries(string_v_char ${LIB_REDIS}) | ||
| 55 | 55 | ||
| 56 | add_executable(multi_client examples/multi-client.cpp ${SRC_ALL}) | 56 | add_executable(multi_client examples/multi-client.cpp ${SRC_ALL}) |
| 57 | target_link_libraries(multi_client ${LIB_REDIS}) | 57 | target_link_libraries(multi_client ${LIB_REDIS}) |
examples/basic.cpp
| @@ -9,7 +9,7 @@ using namespace std; | @@ -9,7 +9,7 @@ using namespace std; | ||
| 9 | 9 | ||
| 10 | int main(int argc, char* argv[]) { | 10 | int main(int argc, char* argv[]) { |
| 11 | 11 | ||
| 12 | - redox::Redox rdx = {"localhost", 6379}; // Initialize Redox | 12 | + redox::Redox rdx = {"localhost", 6379, [](int state) { cout << "Connection state: " << state << endl; }}; // Initialize Redox |
| 13 | if(!rdx.start()) return 1; // Start the event loop | 13 | if(!rdx.start()) return 1; // Start the event loop |
| 14 | 14 | ||
| 15 | rdx.del("occupation"); | 15 | rdx.del("occupation"); |
examples/basic_threaded.cpp
| @@ -13,7 +13,7 @@ redox::Redox rdx = {"localhost", 6379}; | @@ -13,7 +13,7 @@ redox::Redox rdx = {"localhost", 6379}; | ||
| 13 | 13 | ||
| 14 | int main(int argc, char* argv[]) { | 14 | int main(int argc, char* argv[]) { |
| 15 | 15 | ||
| 16 | - rdx.start(); | 16 | + if(!rdx.start()) return 1; |
| 17 | 17 | ||
| 18 | thread setter([]() { | 18 | thread setter([]() { |
| 19 | for(int i = 0; i < 5000; i++) { | 19 | for(int i = 0; i < 5000; i++) { |
examples/data_types.cpp
| @@ -10,7 +10,7 @@ using namespace std; | @@ -10,7 +10,7 @@ using namespace std; | ||
| 10 | int main(int argc, char* argv[]) { | 10 | int main(int argc, char* argv[]) { |
| 11 | 11 | ||
| 12 | redox::Redox rdx; // Initialize Redox (default host/port) | 12 | redox::Redox rdx; // Initialize Redox (default host/port) |
| 13 | - rdx.start(); // Start the event loop | 13 | + if(!rdx.start()) return 1; // Start the event loop |
| 14 | 14 | ||
| 15 | rdx.del("mylist"); | 15 | rdx.del("mylist"); |
| 16 | 16 |
examples/lpush_benchmark.cpp
examples/speed_test_async.cpp
| @@ -18,7 +18,7 @@ double time_s() { | @@ -18,7 +18,7 @@ double time_s() { | ||
| 18 | int main(int argc, char* argv[]) { | 18 | int main(int argc, char* argv[]) { |
| 19 | 19 | ||
| 20 | Redox rdx = {"localhost", 6379}; | 20 | Redox rdx = {"localhost", 6379}; |
| 21 | - rdx.start(); | 21 | + if(!rdx.start()) return 1; |
| 22 | 22 | ||
| 23 | if(rdx.command_blocking("SET simple_loop:count 0")) { | 23 | if(rdx.command_blocking("SET simple_loop:count 0")) { |
| 24 | cout << "Reset the counter to zero." << endl; | 24 | cout << "Reset the counter to zero." << endl; |
examples/speed_test_async_multi.cpp
| @@ -19,7 +19,7 @@ double time_s() { | @@ -19,7 +19,7 @@ double time_s() { | ||
| 19 | int main(int argc, char* argv[]) { | 19 | int main(int argc, char* argv[]) { |
| 20 | 20 | ||
| 21 | Redox rdx = {"localhost", 6379}; | 21 | Redox rdx = {"localhost", 6379}; |
| 22 | - rdx.start(); | 22 | + if(!rdx.start()) return 1; |
| 23 | 23 | ||
| 24 | if(rdx.set("simple_loop:count", "0")) { | 24 | if(rdx.set("simple_loop:count", "0")) { |
| 25 | cout << "Reset the counter to zero." << endl; | 25 | cout << "Reset the counter to zero." << endl; |
examples/speed_test_sync.cpp
| @@ -18,7 +18,7 @@ double time_s() { | @@ -18,7 +18,7 @@ double time_s() { | ||
| 18 | int main(int argc, char* argv[]) { | 18 | int main(int argc, char* argv[]) { |
| 19 | 19 | ||
| 20 | Redox rdx = {"localhost", 6379}; | 20 | Redox rdx = {"localhost", 6379}; |
| 21 | - rdx.start(); | 21 | + if(!rdx.start()) return 1; |
| 22 | 22 | ||
| 23 | if(rdx.command_blocking("SET simple_loop:count 0")) { | 23 | if(rdx.command_blocking("SET simple_loop:count 0")) { |
| 24 | cout << "Reset the counter to zero." << endl; | 24 | cout << "Reset the counter to zero." << endl; |
examples/string_vs_charp.cpp
| @@ -18,7 +18,7 @@ double time_s() { | @@ -18,7 +18,7 @@ double time_s() { | ||
| 18 | int main(int argc, char* argv[]) { | 18 | int main(int argc, char* argv[]) { |
| 19 | 19 | ||
| 20 | Redox rdx; | 20 | Redox rdx; |
| 21 | - rdx.start(); | 21 | + if(!rdx.start()) return 1; |
| 22 | 22 | ||
| 23 | rdx.del("stringtest"); | 23 | rdx.del("stringtest"); |
| 24 | rdx.set("stringtest", "value"); | 24 | rdx.set("stringtest", "value"); |
src/redox.cpp
| @@ -16,19 +16,16 @@ void Redox::connected_callback(const redisAsyncContext *ctx, int status) { | @@ -16,19 +16,16 @@ void Redox::connected_callback(const redisAsyncContext *ctx, int status) { | ||
| 16 | if (status != REDIS_OK) { | 16 | if (status != REDIS_OK) { |
| 17 | cerr << "[ERROR] Connecting to Redis: " << ctx->errstr << endl; | 17 | cerr << "[ERROR] Connecting to Redis: " << ctx->errstr << endl; |
| 18 | rdx->connect_state = REDOX_CONNECT_ERROR; | 18 | rdx->connect_state = REDOX_CONNECT_ERROR; |
| 19 | - rdx->connect_waiter.notify_all(); | ||
| 20 | - return; | ||
| 21 | - } | ||
| 22 | 19 | ||
| 23 | - // Disable hiredis automatically freeing reply objects | ||
| 24 | - ctx->c.reader->fn->freeObject = [](void* reply) {}; | 20 | + } else { |
| 21 | + // Disable hiredis automatically freeing reply objects | ||
| 22 | + ctx->c.reader->fn->freeObject = [](void *reply) {}; | ||
| 23 | + rdx->connect_state = REDOX_CONNECTED; | ||
| 24 | + cout << "[INFO] Connected to Redis." << endl; | ||
| 25 | + } | ||
| 25 | 26 | ||
| 26 | - rdx->connect_state = REDOX_CONNECTED; | ||
| 27 | rdx->connect_waiter.notify_all(); | 27 | rdx->connect_waiter.notify_all(); |
| 28 | - | ||
| 29 | - cout << "[INFO] Connected to Redis." << endl; | ||
| 30 | - | ||
| 31 | - if(rdx->user_connect_callback) rdx->user_connect_callback(); | 28 | + if(rdx->user_connection_callback) rdx->user_connection_callback(rdx->connect_state); |
| 32 | } | 29 | } |
| 33 | 30 | ||
| 34 | void Redox::disconnected_callback(const redisAsyncContext *ctx, int status) { | 31 | void Redox::disconnected_callback(const redisAsyncContext *ctx, int status) { |
| @@ -45,37 +42,36 @@ void Redox::disconnected_callback(const redisAsyncContext *ctx, int status) { | @@ -45,37 +42,36 @@ void Redox::disconnected_callback(const redisAsyncContext *ctx, int status) { | ||
| 45 | 42 | ||
| 46 | rdx->stop_signal(); | 43 | rdx->stop_signal(); |
| 47 | rdx->connect_waiter.notify_all(); | 44 | rdx->connect_waiter.notify_all(); |
| 48 | - | ||
| 49 | - if(rdx->user_disconnect_callback) rdx->user_disconnect_callback(); | 45 | + if(rdx->user_connection_callback) rdx->user_connection_callback(rdx->connect_state); |
| 50 | } | 46 | } |
| 51 | 47 | ||
| 52 | Redox::Redox( | 48 | Redox::Redox( |
| 53 | const string& host, const int port, | 49 | const string& host, const int port, |
| 54 | - std::function<void(void)> connected, | ||
| 55 | - std::function<void(void)> disconnected | ||
| 56 | -) : host(host), port(port), user_connect_callback(connected), user_disconnect_callback(disconnected) { | 50 | + std::function<void(int)> connection_callback |
| 51 | +) : host(host), port(port), user_connection_callback(connection_callback) { | ||
| 57 | 52 | ||
| 58 | - // Required by libev | 53 | + // libev setup |
| 59 | signal(SIGPIPE, SIG_IGN); | 54 | signal(SIGPIPE, SIG_IGN); |
| 55 | + evloop = ev_loop_new(EVFLAG_AUTO); | ||
| 56 | + ev_set_userdata(evloop, (void*)this); // Back-reference | ||
| 60 | 57 | ||
| 61 | // Create a redisAsyncContext | 58 | // Create a redisAsyncContext |
| 62 | ctx = redisAsyncConnect(host.c_str(), port); | 59 | ctx = redisAsyncConnect(host.c_str(), port); |
| 60 | + ctx->data = (void*)this; // Back-reference | ||
| 61 | + | ||
| 63 | if (ctx->err) { | 62 | if (ctx->err) { |
| 64 | - printf("Error: %s\n", ctx->errstr); | 63 | + cout << "[ERROR] Could not create a hiredis context: " << ctx->errstr << endl; |
| 64 | + connect_state = REDOX_CONNECT_ERROR; | ||
| 65 | + connect_waiter.notify_all(); | ||
| 65 | return; | 66 | return; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | - // Create a new event loop and attach it to hiredis | ||
| 69 | - evloop = ev_loop_new(EVFLAG_AUTO); | 69 | + // Attach event loop to hiredis |
| 70 | redisLibevAttach(evloop, ctx); | 70 | redisLibevAttach(evloop, ctx); |
| 71 | 71 | ||
| 72 | // Set the callbacks to be invoked on server connection/disconnection | 72 | // Set the callbacks to be invoked on server connection/disconnection |
| 73 | redisAsyncSetConnectCallback(ctx, Redox::connected_callback); | 73 | redisAsyncSetConnectCallback(ctx, Redox::connected_callback); |
| 74 | redisAsyncSetDisconnectCallback(ctx, Redox::disconnected_callback); | 74 | redisAsyncSetDisconnectCallback(ctx, Redox::disconnected_callback); |
| 75 | - | ||
| 76 | - // Set back references to this Redox object (for use in callbacks) | ||
| 77 | - ev_set_userdata(evloop, (void*)this); | ||
| 78 | - ctx->data = (void*)this; | ||
| 79 | } | 75 | } |
| 80 | 76 | ||
| 81 | void Redox::run_event_loop() { | 77 | void Redox::run_event_loop() { |
src/redox.hpp
| @@ -46,8 +46,7 @@ public: | @@ -46,8 +46,7 @@ public: | ||
| 46 | Redox( | 46 | Redox( |
| 47 | const std::string& host = REDIS_DEFAULT_HOST, | 47 | const std::string& host = REDIS_DEFAULT_HOST, |
| 48 | const int port = REDIS_DEFAULT_PORT, | 48 | const int port = REDIS_DEFAULT_PORT, |
| 49 | - std::function<void(void)> connected = nullptr, | ||
| 50 | - std::function<void(void)> disconnected = nullptr | 49 | + std::function<void(int)> connection_callback = nullptr |
| 51 | ); | 50 | ); |
| 52 | ~Redox(); | 51 | ~Redox(); |
| 53 | 52 | ||
| @@ -184,8 +183,7 @@ private: | @@ -184,8 +183,7 @@ private: | ||
| 184 | std::condition_variable connect_waiter; | 183 | std::condition_variable connect_waiter; |
| 185 | 184 | ||
| 186 | // User connect/disconnect callbacks | 185 | // User connect/disconnect callbacks |
| 187 | - std::function<void(void)> user_connect_callback; | ||
| 188 | - std::function<void(void)> user_disconnect_callback; | 186 | + std::function<void(int)> user_connection_callback; |
| 189 | 187 | ||
| 190 | // Dynamically allocated libev event loop | 188 | // Dynamically allocated libev event loop |
| 191 | struct ev_loop* evloop; | 189 | struct ev_loop* evloop; |