Commit cb37f24f13758ce21f8db7cad87b4a1bb3070789

Authored by Hayk Martirosyan
1 parent a8a81ee7

Add unix sockets constructor

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&lt;ReplyT&gt;::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&amp; 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&lt;ReplyT&gt;* Redox::command_blocking(const std::string&amp; 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  
... ...