-
Separate include directory so that examples can reference the same thing whether installed in the system or from the local folder.
-
Made redox into a more formal package with CMake. It now by default builds a dynamic library in release mode. Tests and examples can be enabled with options. Added semantic versioning. Documented the install from source procedure which is very easy, just make and make install. Users now have to just link one library (redox) and include one header (redox.hpp), and the rest is linked from those. Used CPack to add capability to create a debian package. Useful for getting it into the apt repos. Also redid the readme introduction.
-
More intuitive if disconnect() blocks like connect(). Most clients will want to use these two methods. For more fine grained control, disconnect() is just a combo of stop() and wait().
-
Configure CMake to generate libredox.so and libredox_static.a, and have all examples use the dynamic library. This is how Redox should be used in practice, and greatly reduces the compilation time of the examples. Also renamed redox.[ch]pp to client.[ch]pp and created one master header redox.hpp for users to include. This header right now just includes client.hpp, command.hpp, and subscriber.hpp.
-
Make .free() on commands send a message over an async watcher to the event loop, just like adding commands. This gets rid of some very tough to find memory bugs. Combined .cancel() with .free(), so there is only one method to call, whether for synchronous commands or for looped commands. Also debug some horrible segfaults related to Subscriber. Something is odd with hiredis and subscriptions, need to ask them. It seems when we flood with commands it doesn't disconnect cleanly. Look for a way to wait until all commands are processed.
-
Conform (mostly) to Google C++ guidelines. Apache license notice and link above each core file.
-
Refactor state management code to use three methods .connect(), .disconnect(), and .wait(). Start conforming to uniform coding style already applied to Command class. Split off subscribe functionality into its own class Subscriber. This is good because it was introducing unnecessary state and complexity into the main client. Now, Redox handles publishing like any other command and the Subscriber receives messages.
-
Using free_guard_ as the same mutex in .reply() causes deadlock when a callback accesses .reply(). Make a separate mutex.
-
Also make cmd.reply() copy the value and use a mutex to make it thread safe. No noticable speed hits, probably thanks to RVO.
-
Split up command into command, command_blocking, and command_looping. The original command no longer returns anything, which clarifies how it should be used in most cases. command_looping and command_blocking both return a command object. Also added a waiting CV to the Command object, though it is not used in command_blocking yet.
-
Now, there is only one callback for command(), and it returns a const reference to the Command object. The user is responsible for error checking using c.ok(), c.status(), and getting the reply with c.reply(). This significantly cleans up the library code and the user code. Greatly refactored the data type specialization code in command.cpp.
-
* Member variables with trailing underscore * Methods camelCase * Explicit template instantiation, move definitions to .cpp * Reorder methods to make more sense * Limit public API, comment well
-
subscribe/psubscribe/unsubscribe/punsubscribe methods that keep track of subscribed topics to make sure we don't ask hiredis for bad things. It appears all crashes are eliminated, though no stress testing has been done.
-
subscribe/unsubscribe/publish with proper and working callbacks. Guard added that throws an exception if a non-pubsub command is issued after a subscribe. Also removed all std:: prefixes from redox.cpp. Just made the decision for "using namespace std" there for readability. Not a header, of course. Also added another async watcher for breaking the loop, since ev_break doesn't actually do anything when called outside of an ev_run callback.
-
utils/logger.[ch]pp gives a logger implementation based on ostringstream that is pretty nice. I took this from Stack Overflow and added some things to make syntax nicer. Changed all cout and cerr statements in Redox to be of the form logger.{debug/info/warning/error/fatal}() << stuff. Arguments for non-printed statements are still evaluated. Gives a performance hit if we actually add statements on every callback and run speed tests. For most use cases, doesn't matter. For now, not including such low level output anyway. Would be nice to have a macro to leave out/include the low-level logs at compile-time. -
Implemented limited but useful binary data support without breaking the API. If the last character of the command is a ", look for the first ", and everything in between the quotes treat as binary data. Takes care of setting a key with a binary value. Not useful if there need to be multiple binary entries in one command, or for binary keys. Also need to be careful if the last character of the value actually needs to be a quote, in which case we need to quote the value.
-
Useful based on what kind of data you need.
-
Added GTest under test/. Great for unit testing commands. Added some nice helper functions to make writing tests easy. Added options to CMakeLists to build the library, tests, and examples separately, configurable through ccmake. Also default the build type to RelWithDebInfo, but don't override user settings.
-
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.
-
Better than using a laptop, because it can be reproduced by others much more easily
-
submit_command_callback
-
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.