Commit cb37f24f13758ce21f8db7cad87b4a1bb3070789
1 parent
a8a81ee7
Add unix sockets constructor
Showing
4 changed files
with
53 additions
and
18 deletions
README.md
| ... | ... | @@ -22,7 +22,8 @@ high-performance applications. It is built on top of [hiredis](https://github.co |
| 22 | 22 | ## Performance Benchmarks |
| 23 | 23 | Benchmarks are given by averaging the results of five trials of various programs |
| 24 | 24 | in `examples/`. The results are on an AWS t2.medium instance running Ubuntu 14.04 (64-bit). |
| 25 | -During these tests, Redox communicated with a local Redis server over TCP. | |
| 25 | +During these tests, Redox communicated with a local Redis server over TCP. Results are | |
| 26 | +slightly faster using Unix sockets. | |
| 26 | 27 | |
| 27 | 28 | * 100 repeating asynchronous commands (`speed_test_async_multi`): **710,014 commands/s** |
| 28 | 29 | * One repeating asynchronous command (`speed_test_async`): **195,159 commands/s** | ... | ... |
src/command.hpp
| ... | ... | @@ -70,7 +70,7 @@ public: |
| 70 | 70 | */ |
| 71 | 71 | void free(); |
| 72 | 72 | |
| 73 | - void process_reply(); | |
| 73 | + void process_reply(redisReply* r); | |
| 74 | 74 | |
| 75 | 75 | ev_timer* get_timer() { |
| 76 | 76 | std::lock_guard<std::mutex> lg(timer_guard); |
| ... | ... | @@ -94,7 +94,6 @@ private: |
| 94 | 94 | ev_timer timer; |
| 95 | 95 | std::mutex timer_guard; |
| 96 | 96 | |
| 97 | - | |
| 98 | 97 | // Make sure we don't free resources until details taken care of |
| 99 | 98 | std::mutex free_guard; |
| 100 | 99 | |
| ... | ... | @@ -120,10 +119,11 @@ Command<ReplyT>::Command( |
| 120 | 119 | } |
| 121 | 120 | |
| 122 | 121 | template<class ReplyT> |
| 123 | -void Command<ReplyT>::process_reply() { | |
| 122 | +void Command<ReplyT>::process_reply(redisReply* r) { | |
| 124 | 123 | |
| 125 | 124 | free_guard.lock(); |
| 126 | 125 | |
| 126 | + reply_obj = r; | |
| 127 | 127 | invoke_callback(); |
| 128 | 128 | |
| 129 | 129 | pending--; | ... | ... |
src/redox.cpp
| ... | ... | @@ -45,18 +45,14 @@ void Redox::disconnected_callback(const redisAsyncContext *ctx, int status) { |
| 45 | 45 | if(rdx->user_connection_callback) rdx->user_connection_callback(rdx->connect_state); |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | -Redox::Redox( | |
| 49 | - const string& host, const int port, | |
| 50 | - std::function<void(int)> connection_callback | |
| 51 | -) : host(host), port(port), user_connection_callback(connection_callback) { | |
| 52 | - | |
| 53 | - // libev setup | |
| 48 | +void Redox::init_ev() { | |
| 54 | 49 | signal(SIGPIPE, SIG_IGN); |
| 55 | 50 | evloop = ev_loop_new(EVFLAG_AUTO); |
| 56 | 51 | ev_set_userdata(evloop, (void*)this); // Back-reference |
| 52 | +} | |
| 53 | + | |
| 54 | +void Redox::init_hiredis() { | |
| 57 | 55 | |
| 58 | - // Create a redisAsyncContext | |
| 59 | - ctx = redisAsyncConnect(host.c_str(), port); | |
| 60 | 56 | ctx->data = (void*)this; // Back-reference |
| 61 | 57 | |
| 62 | 58 | if (ctx->err) { |
| ... | ... | @@ -74,6 +70,32 @@ Redox::Redox( |
| 74 | 70 | redisAsyncSetDisconnectCallback(ctx, Redox::disconnected_callback); |
| 75 | 71 | } |
| 76 | 72 | |
| 73 | +Redox::Redox( | |
| 74 | + const string& host, const int port, | |
| 75 | + std::function<void(int)> connection_callback | |
| 76 | +) : host(host), port(port), user_connection_callback(connection_callback) { | |
| 77 | + | |
| 78 | + init_ev(); | |
| 79 | + | |
| 80 | + // Connect over TCP | |
| 81 | + ctx = redisAsyncConnect(host.c_str(), port); | |
| 82 | + | |
| 83 | + init_hiredis(); | |
| 84 | +} | |
| 85 | + | |
| 86 | +Redox::Redox( | |
| 87 | + const std::string& path, | |
| 88 | + std::function<void(int)> connection_callback = nullptr | |
| 89 | +) : path(path), user_connection_callback(connection_callback) { | |
| 90 | + | |
| 91 | + init_ev(); | |
| 92 | + | |
| 93 | + // Connect over unix sockets | |
| 94 | + ctx = redisAsyncConnectUnix(path.c_str()); | |
| 95 | + | |
| 96 | + init_hiredis(); | |
| 97 | +} | |
| 98 | + | |
| 77 | 99 | void Redox::run_event_loop() { |
| 78 | 100 | |
| 79 | 101 | // Events to connect to Redox |
| ... | ... | @@ -200,8 +222,7 @@ void Redox::command_callback(redisAsyncContext *ctx, void *r, void *privdata) { |
| 200 | 222 | return; |
| 201 | 223 | } |
| 202 | 224 | |
| 203 | - c->reply_obj = reply_obj; | |
| 204 | - c->process_reply(); | |
| 225 | + c->process_reply(reply_obj); | |
| 205 | 226 | |
| 206 | 227 | // Increment the Redox object command counter |
| 207 | 228 | rdx->cmd_count++; |
| ... | ... | @@ -340,7 +361,7 @@ void Redox::command(const string& cmd) { |
| 340 | 361 | |
| 341 | 362 | bool Redox::command_blocking(const string& cmd) { |
| 342 | 363 | Command<redisReply*>* c = command_blocking<redisReply*>(cmd); |
| 343 | - bool succeeded = (c->status() == REDOX_OK); | |
| 364 | + bool succeeded = c->ok(); | |
| 344 | 365 | c->free(); |
| 345 | 366 | return succeeded; |
| 346 | 367 | } | ... | ... |
src/redox.hpp
| ... | ... | @@ -48,6 +48,14 @@ public: |
| 48 | 48 | const int port = REDIS_DEFAULT_PORT, |
| 49 | 49 | std::function<void(int)> connection_callback = nullptr |
| 50 | 50 | ); |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Initialize everything, connect over unix sockets to a Redis server. | |
| 54 | + */ | |
| 55 | + Redox( | |
| 56 | + const std::string& path, | |
| 57 | + std::function<void(int)> connection_callback | |
| 58 | + ); | |
| 51 | 59 | ~Redox(); |
| 52 | 60 | |
| 53 | 61 | /** |
| ... | ... | @@ -173,10 +181,17 @@ public: |
| 173 | 181 | |
| 174 | 182 | private: |
| 175 | 183 | |
| 176 | - // Redox server | |
| 184 | + // Redox server over TCP | |
| 177 | 185 | std::string host; |
| 178 | 186 | int port; |
| 179 | 187 | |
| 188 | + // Redox server over unix | |
| 189 | + std::string path; | |
| 190 | + | |
| 191 | + // Setup code for the constructors | |
| 192 | + void init_ev(); | |
| 193 | + void init_hiredis(); | |
| 194 | + | |
| 180 | 195 | // Manage connection state |
| 181 | 196 | std::atomic_int connect_state = {REDOX_NOT_YET_CONNECTED}; |
| 182 | 197 | std::mutex connect_lock; |
| ... | ... | @@ -315,9 +330,7 @@ Command<ReplyT>* Redox::command_blocking(const std::string& cmd) { |
| 315 | 330 | 0, 0, false // No repeats, don't free memory |
| 316 | 331 | ); |
| 317 | 332 | |
| 318 | - // Wait until a callback is invoked | |
| 319 | 333 | cv.wait(lk, [&status] { return status != REDOX_UNINIT; }); |
| 320 | - | |
| 321 | 334 | c->reply_val = val; |
| 322 | 335 | c->reply_status = status; |
| 323 | 336 | ... | ... |