Module: Gitlab::Patch::RedisCacheStore

Defined in:
lib/gitlab/patch/redis_cache_store.rb

Instance Method Summary collapse

Instance Method Details

#delete_multi_entries(entries, **options) ⇒ Object

‘delete_multi_entries` in Rails runs a multi-key `del` command patch will run pipelined single-key `del` for Redis Cluster compatibility



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/gitlab/patch/redis_cache_store.rb', line 17

def delete_multi_entries(entries, **options)
  return super unless enable_rails_cache_pipeline_patch?

  delete_count = 0
  redis.with do |conn|
    entries.each_slice(pipeline_batch_size) do |subset|
      delete_count += Gitlab::Redis::CrossSlot::Pipeline.new(conn).pipelined do |pipeline|
        subset.each { |entry| pipeline.del(entry) }
      end.sum
    end
  end
  delete_count
end

#patched_read_multi_mget(*names) ⇒ Object

Copied from github.com/rails/rails/blob/v6.1.6.1/activesupport/lib/active_support/cache/redis_cache_store.rb re-implements ‘read_multi_mget` using a pipeline of `get`s rather than an `mget`



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/gitlab/patch/redis_cache_store.rb', line 34

def patched_read_multi_mget(*names)
  options = names.extract_options!
  options = merged_options(options)
  return {} if names == []

  raw = options&.fetch(:raw, false)

  keys = names.map { |name| normalize_key(name, options) }

  values = failsafe(:patched_read_multi_mget, returning: {}) do
    redis.with do |c|
      pipeline_mget(c, keys)
    end
  end

  names.zip(values).each_with_object({}) do |(name, value), results|
    if value # rubocop:disable Style/Next
      entry = deserialize_entry(value, raw: raw)
      unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(name, options))
        results[name] = entry.value
      end
    end
  end
end

#pipeline_mget(conn, keys) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/gitlab/patch/redis_cache_store.rb', line 59

def pipeline_mget(conn, keys)
  keys.each_slice(pipeline_batch_size).flat_map do |subset|
    Gitlab::Redis::CrossSlot::Pipeline.new(conn).pipelined do |p|
      subset.each { |key| p.get(key) }
    end
  end
end

#read_multi_mget(*names) ⇒ Object

We will try keep patched code explicit and matching the original signature in github.com/rails/rails/blob/v6.1.7.2/activesupport/lib/active_support/cache/redis_cache_store.rb#L361



8
9
10
11
12
13
# File 'lib/gitlab/patch/redis_cache_store.rb', line 8

def read_multi_mget(*names) # rubocop:disable Style/ArgumentsForwarding
  return super unless enable_rails_cache_pipeline_patch?
  return super unless use_patched_mget?

  patched_read_multi_mget(*names) # rubocop:disable Style/ArgumentsForwarding
end