Class: RedisMemo::Batch

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

Overview

This class facilitates the batching of Redis calls triggered by memoize_method to minimize the number of round trips to Redis.

  • Batches cannot be nested

  • When a batch is still open (while still in the RedisMemo.batch block) the return value of any memoized method is a RedisMemo::Future instead of the actual method value

  • The actual method values are returned as a list, in the same order as invoking, after exiting the block

Examples:

results = RedisMemo.batch do
  5.times { |i| memoized_calculation(i) }
  nil # Not the return value of the block
end
results # [1,2,3,4,5] (results from the memoized_calculation calls)

Class Method Summary collapse

Class Method Details

.closeObject

Closes the current batch, returning the futures in that batch.



37
38
39
40
41
42
43
# File 'lib/redis_memo/batch.rb', line 37

def self.close
  return unless current

  futures = current
  RedisMemo::ThreadLocalVar.batch = nil
  futures
end

.currentObject

Retrieves the current open batch.



46
47
48
# File 'lib/redis_memo/batch.rb', line 46

def self.current
  RedisMemo::ThreadLocalVar.batch
end

.executeObject

Executes all the futures in the current batch using batched calls to Redis and closes it.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/redis_memo/batch.rb', line 52

def self.execute
  futures = close
  return unless futures

  cached_results = {}
  method_cache_keys = nil

  RedisMemo::Tracer.trace('redis_memo.cache.batch.read', nil) do
    method_cache_keys = RedisMemo::MemoizeMethod.__send__(
      :method_cache_keys,
      futures.map(&:context),
    )

    if method_cache_keys
      cached_results = RedisMemo::Cache.read_multi(*method_cache_keys)
    end
  end

  RedisMemo::Tracer.trace('redis_memo.cache.batch.execute', nil) do
    results = Array.new(futures.size)
    futures.each_with_index do |future, i|
      future.method_cache_key = method_cache_keys ? method_cache_keys[i] : ''
      results[i] = future.execute(cached_results)
    end
    results
  end
end

.openObject

Opens a new batch. If a batch is already open, raises an error to prevent nested batches.



28
29
30
31
32
33
34
# File 'lib/redis_memo/batch.rb', line 28

def self.open
  if current
    raise RedisMemo::RuntimeError.new('Batch can not be nested')
  end

  RedisMemo::ThreadLocalVar.batch = []
end