Class: Readthis::Cache

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, options = {}) ⇒ Cache

Creates a new Readthis::Cache object with the given redis URL. The URL is parsed by the redis client directly.

Examples:

Create a new cache instance

Readthis::Cache.new('redis://localhost:6379/0', namespace: 'cache')

Create a compressed cache instance

Readthis::Cache.new('redis://localhost:6379/0', compress: true, compression_threshold: 2048)

Parameters:

  • A (String)

    redis compliant url with necessary connection details

  • [Boolean] (Hash)

    a customizable set of options

  • [Number] (Hash)

    a customizable set of options

  • [Module] (Hash)

    a customizable set of options

  • [String] (Hash)

    a customizable set of options



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/readthis/cache.rb', line 43

def initialize(url, options = {})
  @expires_in = options.fetch(:expires_in, nil)
  @namespace  = options.fetch(:namespace,  nil)

  @entity = Readthis::Entity.new(
    marshal:   options.fetch(:marshal, Marshal),
    compress:  options.fetch(:compress, false),
    threshold: options.fetch(:compression_threshold, 1024)
  )

  @pool = ConnectionPool.new(pool_options(options)) do
    Redis.new(url: url, driver: :hiredis)
  end
end

Instance Attribute Details

#entityObject (readonly)

Returns the value of attribute entity.



11
12
13
# File 'lib/readthis/cache.rb', line 11

def entity
  @entity
end

#expires_inObject (readonly)

Returns the value of attribute expires_in.



11
12
13
# File 'lib/readthis/cache.rb', line 11

def expires_in
  @expires_in
end

#namespaceObject (readonly)

Returns the value of attribute namespace.



11
12
13
# File 'lib/readthis/cache.rb', line 11

def namespace
  @namespace
end

#poolObject (readonly)

Returns the value of attribute pool.



11
12
13
# File 'lib/readthis/cache.rb', line 11

def pool
  @pool
end

Class Method Details

.notificationsObject

Provide a class level lookup of the proper notifications module. Instrumention is expected to occur within applications that have ActiveSupport::Notifications available, but needs to work even when it isn’t.



17
18
19
20
21
22
23
# File 'lib/readthis/cache.rb', line 17

def self.notifications
  if Object.const_defined?('ActiveSupport::Notifications')
    ActiveSupport::Notifications
  else
    Readthis::Notifications
  end
end

Instance Method Details

#clearObject



193
194
195
# File 'lib/readthis/cache.rb', line 193

def clear
  invoke(:clear, '*', &:flushdb)
end

#decrement(key, amount = 1, options = {}) ⇒ Object

Decrement a key in the store.

If the key doesn’t exist it will be initialized at 0. If the key exists but it isn’t a Fixnum it will be initialized at 0.

Examples:


cache.write('counter', 20) # => 20
cache.decrement('counter') # => 19
cache.decrement('counter', 2) # => 17

Parameters:

  • Key (String)

    for lookup

  • Value (Fixnum)

    to decrement by

  • Optional (Hash)

    overrides



144
145
146
147
148
# File 'lib/readthis/cache.rb', line 144

def decrement(key, amount = 1, options = {})
  invoke(:decrement, key) do |store|
    alter(key, amount * -1, options)
  end
end

#delete(key, options = {}) ⇒ Object



91
92
93
94
95
# File 'lib/readthis/cache.rb', line 91

def delete(key, options = {})
  invoke(:delete, key) do |store|
    store.del(namespaced_key(key, merged_options(options)))
  end
end

#exist?(key, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


187
188
189
190
191
# File 'lib/readthis/cache.rb', line 187

def exist?(key, options = {})
  invoke(:exist?, key) do |store|
    store.exists(namespaced_key(key, merged_options(options)))
  end
end

#fetch(key, options = {}) ⇒ Object



97
98
99
100
101
102
103
104
105
106
# File 'lib/readthis/cache.rb', line 97

def fetch(key, options = {})
  value = read(key, options) unless options[:force]

  if value.nil? && block_given?
    value = yield(key)
    write(key, value, options)
  end

  value
end

#fetch_multi(*keys) ⇒ Object

Fetches multiple keys from the cache using a single call to the server and filling in any cache misses. All read and write operations are executed atomically.

cache.fetch_multi('alpha', 'beta') do |key|
  "#{key}-was-missing"
end


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/readthis/cache.rb', line 168

def fetch_multi(*keys)
  results = read_multi(*keys)
  options = merged_options(extract_options!(keys))

  invoke(:fetch_multi, keys) do |store|
    store.pipelined do
      results.each do |key, value|
        if value.nil?
          value = yield key
          write(key, value, options)
          results[key] = value
        end
      end
    end

    results
  end
end

#increment(key, amount = 1, options = {}) ⇒ Object

Increment a key in the store.

If the key doesn’t exist it will be initialized at 0. If the key exists but it isn’t a Fixnum it will be initialized at 0.

Examples:


cache.increment('counter') # => 0
cache.increment('counter') # => 1
cache.increment('counter', 2) # => 3

Parameters:

  • Key (String)

    for lookup

  • Value (Fixnum)

    to increment by

  • Optional (Hash)

    overrides



123
124
125
126
127
# File 'lib/readthis/cache.rb', line 123

def increment(key, amount = 1, options = {})
  invoke(:incremenet, key) do |store|
    alter(key, amount, options)
  end
end

#read(key, options = {}) ⇒ Object

Fetches data from the cache, using the given key. If there is data in the cache with the given key, then that data is returned. Otherwise, nil is returned.

Examples:


cache.read('missing') # => nil
cache.read('matched') # => 'some value'

Parameters:

  • Key (String)

    for lookup

  • Optional (Hash)

    overrides



70
71
72
73
74
75
76
# File 'lib/readthis/cache.rb', line 70

def read(key, options = {})
  invoke(:read, key) do |store|
    value = store.get(namespaced_key(key, merged_options(options)))

    entity.load(value)
  end
end

#read_multi(*keys) ⇒ Object



150
151
152
153
154
155
156
157
158
159
# File 'lib/readthis/cache.rb', line 150

def read_multi(*keys)
  options = merged_options(extract_options!(keys))
  mapping = keys.map { |key| namespaced_key(key, options) }

  invoke(:read_multi, keys) do |store|
    values = store.mget(mapping).map { |value| entity.load(value) }

    keys.zip(values).to_h
  end
end

#write(key, value, options = {}) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/readthis/cache.rb', line 78

def write(key, value, options = {})
  options    = merged_options(options)
  namespaced = namespaced_key(key, options)

  invoke(:write, key) do |store|
    if expiration = options[:expires_in]
      store.setex(namespaced, expiration, entity.dump(value))
    else
      store.set(namespaced, entity.dump(value))
    end
  end
end