Class: DiscourseRedis

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

Overview

A wrapper around redis that namespaces keys with the current site id

Defined Under Namespace

Classes: EvalHelper

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = nil, namespace: true, raw_redis: nil) ⇒ DiscourseRedis

Returns a new instance of DiscourseRedis.



17
18
19
20
21
# File 'lib/discourse_redis.rb', line 17

def initialize(config = nil, namespace: true, raw_redis: nil)
  @config = config || DiscourseRedis.config
  @redis = raw_redis || DiscourseRedis.raw_connection(@config.dup)
  @namespace = namespace
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, **kwargs, &block) ⇒ Object

prefix the key with the namespace



40
41
42
43
44
45
46
# File 'lib/discourse_redis.rb', line 40

def method_missing(meth, *args, **kwargs, &block)
  if @redis.respond_to?(meth)
    DiscourseRedis.ignore_readonly { @redis.public_send(meth, *args, **kwargs, &block) }
  else
    super
  end
end

Class Method Details

.configObject



13
14
15
# File 'lib/discourse_redis.rb', line 13

def self.config
  GlobalSetting.redis_config
end

.ignore_readonlyObject



28
29
30
31
32
33
34
35
36
37
# File 'lib/discourse_redis.rb', line 28

def self.ignore_readonly
  yield
rescue Redis::CommandError => ex
  if ex.message =~ /READONLY/
    Discourse.received_redis_readonly!
    nil
  else
    raise ex
  end
end

.new_redis_storeObject



232
233
234
# File 'lib/discourse_redis.rb', line 232

def self.new_redis_store
  Cache.new
end

.raw_connection(config = nil) ⇒ Object



8
9
10
11
# File 'lib/discourse_redis.rb', line 8

def self.raw_connection(config = nil)
  config ||= self.config
  Redis.new(config)
end

Instance Method Details

#del(*keys) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/discourse_redis.rb', line 167

def del(*keys)
  DiscourseRedis.ignore_readonly do
    keys = keys.flatten(1)
    keys.map! { |k| "#{namespace}:#{k}" } if @namespace
    @redis.del(*keys)
  end
end

#exists(*args) ⇒ Object



152
153
154
155
# File 'lib/discourse_redis.rb', line 152

def exists(*args)
  args.map! { |a| "#{namespace}:#{a}" } if @namespace
  DiscourseRedis.ignore_readonly { @redis.exists(*args) }
end

#exists?(*args) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
160
# File 'lib/discourse_redis.rb', line 157

def exists?(*args)
  args.map! { |a| "#{namespace}:#{a}" } if @namespace
  DiscourseRedis.ignore_readonly { @redis.exists?(*args) }
end

#keys(pattern = nil) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/discourse_redis.rb', line 201

def keys(pattern = nil)
  DiscourseRedis.ignore_readonly do
    pattern = pattern || "*"
    pattern = "#{namespace}:#{pattern}" if @namespace
    keys = @redis.keys(pattern)

    if @namespace
      len = namespace.length + 1
      keys.map! { |k| k[len..-1] }
    end

    keys
  end
end

#mget(*args) ⇒ Object



162
163
164
165
# File 'lib/discourse_redis.rb', line 162

def mget(*args)
  args.map! { |a| "#{namespace}:#{a}" } if @namespace
  DiscourseRedis.ignore_readonly { @redis.mget(*args) }
end

#multiObject



236
237
238
239
240
241
242
243
244
245
246
# File 'lib/discourse_redis.rb', line 236

def multi
  DiscourseRedis.ignore_readonly do
    if block_given?
      @redis.multi do |transaction|
        yield DiscourseRedis.new(@config, namespace: @namespace, raw_redis: transaction)
      end
    else
      @redis.multi
    end
  end
end

#namespaceObject



228
229
230
# File 'lib/discourse_redis.rb', line 228

def namespace
  RailsMultisite::ConnectionManagement.current_db
end

#namespace_key(key) ⇒ Object



220
221
222
223
224
225
226
# File 'lib/discourse_redis.rb', line 220

def namespace_key(key)
  if @namespace
    "#{namespace}:#{key}"
  else
    key
  end
end

#pipelinedObject



248
249
250
251
252
253
254
255
256
257
258
# File 'lib/discourse_redis.rb', line 248

def pipelined
  DiscourseRedis.ignore_readonly do
    if block_given?
      @redis.pipelined do |transaction|
        yield DiscourseRedis.new(@config, namespace: @namespace, raw_redis: transaction)
      end
    else
      @redis.pipelined
    end
  end
end

#reconnectObject



216
217
218
# File 'lib/discourse_redis.rb', line 216

def reconnect
  @redis._client.reconnect
end

#scan_each(options = {}, &block) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/discourse_redis.rb', line 175

def scan_each(options = {}, &block)
  DiscourseRedis.ignore_readonly do
    match = options[:match].presence || "*"

    options[:match] = if @namespace
      "#{namespace}:#{match}"
    else
      match
    end

    if block
      @redis.scan_each(**options) do |key|
        key = remove_namespace(key) if @namespace
        block.call(key)
      end
    else
      @redis
        .scan_each(**options)
        .map do |key|
          key = remove_namespace(key) if @namespace
          key
        end
    end
  end
end

#without_namespaceObject



23
24
25
26
# File 'lib/discourse_redis.rb', line 23

def without_namespace
  # Only use this if you want to store and fetch data that's shared between sites
  @redis
end