-
Consolidated user callbacks into one, improved some logic.
-
Created an atomic_int connect_state that keeps track of not yet connected, connected, disconnected, and errors. Used to implement good error behavior when the server is down and you start() a Redox instance, or when the server goes down in the middle of running commands. Now, nothing should hang, but should return errors (or throw exceptions) when the server goes down. Also added hooks for a user connect/disconnect callback in the constructor, which is helpful for client programs. Added an example with three Redox clients in one thread.
-
Finally getting rid of the busy loop in the event thread. Now, we use an ev_async watcher that processes commands in the queue, which we can signal in a thread-safe manner using ev_async_send.
-
Instead of busy looping event thread, use a condition variable that is notified every time a command is sent or received, or every 100 milliseconds anyway.
-
Also plan to add in set<string> and unordered_set<string>. Maybe queue<string>. Looking at likely removing char* as an option, if it shows to be about the same speed as string.
-
Thoroughly cleaned up redox.hpp to expose a minimal public API, and commented those well. Generally cleaned up a bunch of stuff. Added wrapper function DEL, which could be useful.
-
Easy few lines for get and set commands that are easy to use. Implemented a condition variable that blocks run() until the event loop is running and Redis is connected. Also added a check to command() that will throw an exception if you try to add a command before calling run().
-
Fixed a couple of bugs found with a test case of 100 parallel asynchronous clients. As of now, there are no known memory leaks, segfaults, or deadlocks in Redox.
-
Ran into a nasty segfault when using 100 parallel asynchronous command loops, where a command's address would match up with a previous command's address. To circumvent the whole issue, Redox keeps a counter of how many Commands it has created and assigns each Command a unique id in the order they are created. Changed all data structures and methods to pass around Command IDs, so nothing uses void* anymore. I consider this a very good thing, but it did seem to slow down performance 20-30% because of the extra lookups. Will see if there's a solution later.
-
Take that, hours of debugging memory leaks! Did lots of structural tweaks to more smartly keep track of commands and make sure everything is evenutally freed from the heap.
-
Created a pointer Command.rdx (Redox*) to allow commands to increment Redox.cmd_count, and simplify a couple of other things. Did a little bit of moving and renaming context objects, so the context is always .ctx and commands can always be called c.
-
Added Command<nullptr_t> which successfully returns NIL replies from Redis, with REDOX_OK. Also renamed constants from REDISX_ -> REDOX_. Moved a bunch of code from redox.cpp into command.cpp, where it logically makes more sense.
-
Move as much as possible into the .cpp file, and clean things up.