• 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.
    Hayk Martirosyan authored
     
    Browse Dir »


  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »
  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »


  • Consolidated user callbacks into one, improved some logic.
    Hayk Martirosyan authored
     
    Browse Dir »
  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »





  • 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().
    Hayk Martirosyan authored
     
    Browse Dir »
  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »
  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »
  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »

  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »
  • 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.
    Hayk Martirosyan authored
     
    Browse Dir »
  • Move as much as possible into the .cpp file, and clean things up.
    Hayk Martirosyan authored
     
    Browse Dir »
  • Found out that ev_timer watchers have a void* data that allows
    currying information to the libev callbacks! That means I could
    stick the Command* in there and completely get rid of the global
    timer_callbacks map that was needed before.
    
    Additionally, we can move ev_timer into the Command object instead
    of separately allocating it on the heap. Simplifies management.
    
    Implemented a synchronous loop speed test based on the latest
    and greatest command_blocking(). Happy to see it is around
    30k/s, which is 100% network delays.
    Hayk Martirosyan authored
     
    Browse Dir »
  • Several hours of multithreaded debugging to find a nasty extra
    ampersand. command_blocking() now returns a Command object with
    the value and status accessible through methods.
    
    Added the option to free memory or not for Command objects when
    command() is called. If free_memory = true, then the Command
    object is freed after the callback or error callback returns.
    If free_memory = false, then the user must call cmd->free().
    
    To implement this, we have to pass in a blank function to the
    freeObject entry in the hiredis redisReader, because otherwise
    it automatically frees memory. This was not cool for the blocking
    case.
    Hayk Martirosyan authored
     
    Browse Dir »

  • Implemented error callbacks for command(). Now, either the success
    or error callbacks are guaranteed to return for any command. Added
    constants for error types.
    
    Many improvements and fixes for memory management. Command objects
    keep track of pending replies and delete themselves when completed.
    
    Changed ReplyT value to remove the const and reference requirements.
    Now, you do command<ReplyT> and the callback should take a
    const ReplyT&, whatever the type is. Makes things more uniform.
    Hayk Martirosyan authored
     
    Browse Dir »


  • Hayk Martirosyan authored
     
    Browse Dir »
  • The event loop (now libev) now runs in a separate detached thread,
    which is abstracted away from the user, who only calls a nonblocking
    .start() method. This thread loops continously, alternating telling
    Redis about asynchronous commands ready to send, and running one
    iteration of the event loop, where all pending events are taken
    care of. This greatly simplifies the user code.
    
    Additionally, some clever tricker is implemented now to handle
    memory management well with the templated command types. The
    difficulty comes from the fact that we pass redis a void pointer
    only, and must retreive everything from that (so, we can't use
    shared_ptr for the whole thing). Thus, we use maps of void pointers
    to their templated data structure pointers, where the memory address
    of the pointer serves as the key.
    Hayk Martirosyan authored
     
    Browse Dir »