nateware / redis-objects

Map Redis types directly to Ruby objects
Artistic License 2.0
2.09k stars 229 forks source link

SortedSet methods like #rangebyscore broken with redis_object >= 0.9.1 and use of multi #162

Open scotttam opened 9 years ago

scotttam commented 9 years ago

Up until redis-objects 0.8.0, it was possible to do something like the following so one could atomically find and remove elements from a SortedSet with a rangebyscore.

require 'redis'
require 'redis/objects'
require 'redis/sorted_set'

class Obj
  include Redis::Objects
  sorted_set :things

  def id
    rand(1_000_000)
  end

  def add(idx)
    self.things.add(idx, idx)
  end

  def pop_things(pop_size)
    results = self.redis.multi do
      self.things.rangebyscore(0, pop_size)
      self.things.remrangebyscore(0, pop_size)
    end
  end
end

obj = Obj.new
100.times { |idx| obj.add(idx) }
puts obj.pop_things(10)

With the introduction of the following commit (0.9.1), this functionality has been broken. Trying to map and unmarshal all the items would work fine if we're not in a multi block. But when in a multi-block, the result is a Redis::Future object.

https://github.com/nateware/redis-objects/commit/7c41fb6#diff-f4e12a534beaeeff971c9c7b3a1e67e2R123

/Users/me/.rvm/gems/ruby-2.0.0-p353@redis-example/gems/redis-objects-0.9.1/lib/redis/sorted_set.rb:122:in `rangebyscore': undefined method `map' for <Redis::Future [:zrangebyscore, "obj:885330:things", 0, 10]>:Redis::Future (NoMethodError)
from redis-example.rb:20:in `block in pop_things'
from /Users/me/.rvm/gems/ruby-2.0.0-p353@redis-example/gems/redis-3.2.0/lib/redis.rb:2148:in `block in multi'
from /Users/me/.rvm/gems/ruby-2.0.0-p353@redis-example/gems/redis-3.2.0/lib/redis.rb:37:in `block in synchronize'
from /Users/me/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
from /Users/me/.rvm/gems/ruby-2.0.0-p353@redis-example/gems/redis-3.2.0/lib/redis.rb:37:in `synchronize'
from /Users/me/.rvm/gems/ruby-2.0.0-p353@redis-example/gems/redis-3.2.0/lib/redis.rb:2141:in `multi'
from redis-example.rb:19:in `pop_things'
from redis-example.rb:33:in `<main>'
nateware commented 9 years ago

Unfortunately this is not an issue with redis-objects, it's because redis.rb changed multi to return a Redis::Future object. There's another ticket in here open on it. I can't revert the commit you linked because it fixed other bugs with nested arrays.