Class: MultiRedis::Executor

Inherits:
Object
  • Object
show all
Defined in:
lib/multi_redis.rb

Instance Method Summary collapse

Constructor Details

#initialize(operations, options = {}) ⇒ Executor

Returns a new instance of Executor.



60
61
62
63
64
# File 'lib/multi_redis.rb', line 60

def initialize operations, options = {}
  @operations = operations
  @arguments = options[:args] || []
  @redis = options[:redis]
end

Instance Method Details

#execute(options = {}) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/multi_redis.rb', line 66

def execute options = {}

  redis = @redis || MultiRedis.redis
  contexts = Array.new(@operations.length){ |i| Context.new redis }
  stacks = @operations.collect{ |op| op.steps.dup }
  args = stacks.collect.with_index{ |a,i| @arguments[i] || [] }
  final_results = Array.new @operations.length

  while stacks.any? &:any?

    # execute all non-multi steps
    stacks.each_with_index do |steps,i|
      final_results[i] = steps.shift.execute(contexts[i], args[i]) while steps.first && !steps.first.multi_type
    end

    # execute all pipelined steps, if any
    pipelined_steps = stacks.collect{ |steps| steps.first && steps.first.multi_type == :pipelined ? steps.shift : nil }
    if pipelined_steps.any?
      results = []
      redis.pipelined do
        pipelined_steps.each_with_index do |step,i|
          if step
            final_results[i] = step.execute(contexts[i], args[i])
            contexts[i].last_results = redis.client.futures[results.length, redis.client.futures.length]
            results += contexts[i].last_results
          end
        end
      end
      pipelined_steps.each_with_index{ |step,i| contexts[i].resolve_futures! if step }
    end

    # execute all multi steps, if any
    multi_steps = stacks.collect{ |steps| steps.first && steps.first.multi_type == :multi ? steps.shift : nil }
    if multi_steps.any?
      results = []
      redis.multi do
        multi_steps.each_with_index do |step,i|
          if step
            final_results[i] = step.execute(contexts[i], args[i])
            contexts[i].last_results = redis.client.futures[results.length, redis.client.futures.length]
            results += contexts[i].last_results
          end
        end
      end
      multi_steps.each_with_index{ |step,i| contexts[i].resolve_futures! if step }
    end
  end

  final_results
end