0.0
No commit activity in last 3 years
No release in over 3 years
Allows you to organize your redis calls in separate classes but still execute them atomically with pipelined or multi.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
 Dependencies

Development

~> 1.5
~> 0.7
~> 2.0
~> 10.1
~> 2.14
~> 0.8

Runtime

~> 3.0
 Project Readme

Multi Redis

Pattern to execute separate redis-rb operations in the same command pipeline or multi/exec.

Gem Version Dependency Status Build Status Coverage Status

Installation

Put this in your Gemfile:

gem 'multi_redis', '~> 0.3.0'

Then run bundle install.

Usage

Assume you have two separate methods that call redis:

$redis = Redis.new
$redis.set 'key1', 'foo'
$redis.set 'key2', 'bar'

class MyRedisClass

  def do_stuff
    $redis.get 'key1'
  end

  def do_other_stuff
    $redis.get 'key2'
  end
end

o = MyRedisClass.new
o.do_stuff         #=> "foo"
o.do_other_stuff   #=> "bar"

This works, but the redis client executes two separate requests to the server, and waits for the result of the first one to start the second one:

Request 1:
- GET key1

Request 2:
- GET key2

The redis-rb gem allows you to run both calls in the same command pipeline:

results = $redis.pipelined do
  $redis.get 'key1'
  $redis.get 'key2'
end

results[0]   #=> "foo"
results[1]   #=> "bar"

There is only one request now, but the two $redis.get calls are no longer in separate methods. To keep them separate, you would have to write your methods so that they could be called in a pipeline. But in a pipeline redis calls return futures, not values, because the calls have not been executed yet.

Multi Redis provides a pattern to more easily handle these futures. It allows you to structure your code so that your separate redis calls may be executed together in one request when needed.

$redis = Redis.new
$redis.set 'key1', 'foo'
$redis.set 'key2', 'bar'

MultiRedis.redis = $redis   # Give Multi Redis a redis-rb client to use.

# Create a redis operation, i.e. an operation that performs redis calls, equivalent to the first method.
do_stuff = MultiRedis::Operation.new do
  pipelined{ |mr| mr.redis.get 'key1' }   # Run your redis command in a pipelined block. It will return a future.
  run{ |mr| mr.last_replies[0] }        # Access the result in a run block. The future has been resolved.
end

# Executing the operation will run all blocks in order and return the result of the last block.
do_stuff.execute   #=> "foo"

# Create another redis operation for the other method.
do_other_stuff = MultiRedis::Operation.new do
  pipelined{ |mr| mr.redis.get 'key2' }
  run{ |mr| mr.last_replies[0] }
end

do_other_stuff.execute   #=> "bar"

The two operations can still be executed separately like before, but they can also be combined through Multi Redis:

MultiRedis.execute do_stuff, do_other_stuff

Both redis calls get grouped into the same command pipeline:

One request:
- GET foo
- GET bar

The array of results is returned by the execute call:

MultiRedis.execute do_stuff, do_other_stuff   #=> [ "foo", "bar" ]

Meta

  • Author: Simon Oulevay (Alpha Hydrae)
  • License: MIT (see LICENSE.txt)