[rust-dev] redis-rs Pipelining and Connections

Armin Ronacher armin.ronacher at active-4.com
Sun Jan 19 12:58:53 PST 2014


Hi,

I'm currently wrapping all of redis in a fairly high-level library similar to 
the Python binding.  It's currently living here:
   https://github.com/mitsuhiko/redis-rs

In general I did not encounter many problems with that but there are some open 
questions in regards to how pipelining and connection pooling should work.

In general, this is roughly how the library works:

   extern mod redis;

   fn main() {
     let client = redis::Client::open("redis://127.0.0.1/").unwrap();
     let mut con = client.get_connection().unwrap();
     println!("Got value: {}", con.get("my_key").unwrap_or("<no value>"));
   }

Pipelining:

I currently have no idea how to implement this.  The API I had in mind was this:

   let mut con = client.get_connection().unwrap();
   let mut counter, data;
   con.pipeline()
     .incr("counter").tap(|value| { counter = value; })
     .get("data_key").tap(|value| { data = value; })
     .execute();

The general idea is pretty simple: whereas a regular redis connection 
immediately returns the results the pipeline buffers them up and will execute 
the tap'ed callbacks to return the data.  Unfortunately I have no idea how this 
can be implemented currently.  There are two issues with that:  first of all I 
don't fancy implementing all methods twice (once for the connection and once for 
the pipeline), secondly the .tap() method needs to change signature depending on 
the return value of the most recent operation.

Lastly because the pipeline borrows the connection as mutable the code currently 
would need to be placed in a separate scope, otherwise the con object becomes 
unusable after the pipeline call.

Connections:

I don't know what the best way to deal with connections is.  Right now I have a 
client object which tries to connect to redis and does the address resolution. 
The actual connection however is provided by a get_connection() function on it 
which will connect and return a connection object.  This way two tasks can have 
a connection each.  I was thinking of extending this with a connection pool but 
I'm not sure how to do this properly since I don't want that the client needs to 
be mutable to get a connection.  That would make it much harder to use with 
multiple tasks.


If anyone has some ideas of how to advance I would love to get some feedback. 
I'm running a bit into a wall here.


Regards,
Armin


More information about the Rust-dev mailing list