void Redox::connectedCallback(const redisAsyncContext *ctx, int status) { Redox *rdx = (Redox *)ctx->data; if (status != REDIS_OK) { rdx->logger_.fatal() << "Could not connect to Redis: " << ctx->errstr; rdx->logger_.fatal() << "Status: " << status; unique_lock<mutex> lk(rdx->connect_lock_); rdx->connect_state_ = CONNECT_ERROR; } else { rdx->logger_.info() << "Connected to Redis."; unique_lock<mutex> lk(rdx->connect_lock_); // Disable hiredis automatically freeing reply objects ctx->c.reader->fn->freeObject = [](void *reply) {}; rdx->connect_state_ = CONNECTED; } int state; { unique_lock<mutex> lk(rdx->connect_lock_); state = rdx->connect_state_; } rdx->connect_waiter_.notify_all(); if (rdx->user_connection_callback_) rdx->user_connection_callback_(state); }
void Redox::disconnectedCallback(const redisAsyncContext *ctx, int status) { Redox *rdx = (Redox *)ctx->data; if (status != REDIS_OK) { rdx->logger_.error() << "Disconnected from Redis on error: " << ctx->errstr; unique_lock<mutex> lk(rdx->connect_lock_); rdx->connect_state_ = DISCONNECT_ERROR; } else { rdx->logger_.info() << "Disconnected from Redis as planned."; unique_lock<mutex> lk(rdx->connect_lock_); rdx->connect_state_ = DISCONNECTED; } rdx->stop(); int state; { unique_lock<mutex> lk(rdx->connect_lock_); state = rdx->connect_state_; } rdx->connect_waiter_.notify_all(); if (rdx->user_connection_callback_) rdx->user_connection_callback_(state); }
int main(int argc, char* argv[]) { Redox rdx; rdx.noWait(true); if(!rdx.connect("localhost", 6379)) return 1; if(rdx.commandSync({"SET", "simple_loop:count", "0"})) { cout << "Reset the counter to zero." << endl; } else { cerr << "Failed to reset counter." << endl; return 1; } double t = 5; // s cout << "Sending \"" << "INCR simple_loop:count" << "\" synchronously for " << t << "s..." << endl; double t0 = time_s(); double t_end = t0 + t; int count = 0; while(time_s() < t_end) { Command<int>& c = rdx.commandSync<int>({"INCR", "simple_loop:count"}); if(!c.ok()) cerr << "Bad reply, code: " << c.status() << endl; c.free(); count++; } double t_elapsed = time_s() - t0; double actual_freq = (double)count / t_elapsed; long final_count = stol(rdx.get("simple_loop:count")); cout << "Sent " << count << " commands in " << t_elapsed << "s, " << "that's " << actual_freq << " commands/s." << endl; cout << "Final value of counter: " << final_count << endl; rdx.disconnect(); return 0; }
int main(int argc, char* argv[]) { string usage_string = "Usage: " + string(argv[0]) + " --(set-async|get-async|set-sync|get-sync|get-pubsub|set-pubsub) [freq]"; if(argc != 3) { cerr << usage_string<< endl; return 1; } bool nowait = true; std::string host = "localhost"; int port = 6379; Redox rdx; if(nowait) rdx.noWait(true); Subscriber rdx_sub; if(nowait) rdx_sub.noWait(true); double freq = stod(argv[2]); // Hz double dt = 1 / freq; // s int iter = 1000000; atomic_int count(0); double t0 = time_s(); double t = t0; double t_new = t; double t_last_reply = t; double t_this_reply = t; if(!strcmp(argv[1], "--get-async")) { if(!rdx.connect(host, port)) return 1; while(count < iter) { rdx.command<string>({"GET", "jitter_test:time"}, [&](Command<string>& c) { if (!c.ok()) { cerr << "Bad reply: " << c.status() << endl; } else { t_new = time_s(); t_this_reply = stod(c.reply()); print_time( t_new - t0, t_new - t, t_this_reply - t_last_reply, t_new - t_this_reply ); t = t_new; t_last_reply = t_this_reply; } count++; if (count == iter) rdx.stop(); } ); this_thread::sleep_for(chrono::microseconds((int)(dt * 1e6))); } } else if(!strcmp(argv[1], "--get-async-loop")) { if(!rdx.connect(host, port)) return 1; rdx.commandLoop<string>({"GET", "jitter_test:time"}, [&](Command<string>& c) { if (!c.ok()) { cerr << "Bad reply: " << c.status() << endl; } else { t_new = time_s(); t_this_reply = stod(c.reply()); print_time( t_new - t0, t_new - t, t_this_reply - t_last_reply, t_new - t_this_reply ); t = t_new; t_last_reply = t_this_reply; } count++; if (count == iter) rdx.stop(); }, dt ); } else if(!strcmp(argv[1], "--set-async")) { if(!rdx.connect(host, port)) return 1; while (count < iter) { rdx.command<string>({"SET", "jitter_test:time", to_string(time_s())}, [&](Command<string>& c) { if (!c.ok()) { cerr << "Error setting value: " << c.status() << endl; } count++; if (count == iter) rdx.stop(); } ); this_thread::sleep_for(chrono::microseconds((int) (dt * 1e6))); } } else if(!strcmp(argv[1], "--get-sync")) { if(!rdx.connect(host, port)) return 1; while(count < iter) { Command<string>& c = rdx.commandSync<string>({"GET", "jitter_test:time"}); if(!c.ok()) { cerr << "Error setting value: " << c.status() << endl; } else { t_new = time_s(); t_this_reply = stod(c.reply()); print_time( t_new - t0, t_new - t, t_this_reply - t_last_reply, t_new - t_this_reply ); t = t_new; t_last_reply = t_this_reply; } count++; if(count == iter) rdx.stop(); c.free(); this_thread::sleep_for(chrono::microseconds((int)((dt) * 1e6))); } } else if(!strcmp(argv[1], "--set-sync")) { if(!rdx.connect(host, port)) return 1; while(count < iter){ Command<string>& c = rdx.commandSync<string>({"SET", "jitter_test:time", to_string(time_s())}); if(!c.ok()) { cerr << "Error setting value: " << c.status() << endl; } count++; if(count == iter) rdx.stop(); c.free(); this_thread::sleep_for(chrono::microseconds((int)((dt) * 1e6))); } } else if(!strcmp(argv[1], "--get-pubsub")) { if(!rdx_sub.connect(host, port)) return 1; auto got_message = [&](const string& topic, const string& msg) { t_new = time_s(); t_this_reply = stod(msg); print_time( t_new - t0, t_new - t, t_this_reply - t_last_reply, t_new - t_this_reply ); t = t_new; t_last_reply = t_this_reply; count++; if (count == iter) rdx.stop(); }; rdx_sub.subscribe("jitter_test:time", got_message); } else if(!strcmp(argv[1], "--set-pubsub")) { if(!rdx.connect(host, port)) return 1; while (count < iter) { double t1 = time_s(); rdx.command<int>({"PUBLISH", "jitter_test:time", to_string(time_s())}, [&](Command<int>& c) { if (!c.ok()) { cerr << "Error setting value: " << c.status() << endl; } count++; if (count == iter) rdx.stop(); } ); double wait = dt - (time_s() - t1); this_thread::sleep_for(chrono::microseconds((int) (wait * 1e6))); } } else { cerr << usage_string << endl; return 1; } rdx.wait(); rdx_sub.wait(); return 0; };