Class: Rimcache::Store

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

Overview

The core of Rimcache. Stores frozen objects in a Hash while tracking when they were last stored and when they were last updated by any process connected to the same cross-process expiry cache.

Access this via Rimcache.store for a singleton instance.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStore

Returns a new instance of Store.



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rimcache/store.rb', line 16

def initialize
  @config = Config.new
  @cached = {}
  @written_at = {}
  @last_check = Time.current

  # @expiry_cache is set on first demand to give the best chance
  # that Rails.cache is loaded when we try to access it
  @expiry_cache = nil
  @expiry = nil
end

Instance Attribute Details

#cachedObject

Returns the value of attribute cached.



14
15
16
# File 'lib/rimcache/store.rb', line 14

def cached
  @cached
end

#configObject

Returns the value of attribute config.



14
15
16
# File 'lib/rimcache/store.rb', line 14

def config
  @config
end

Instance Method Details

#expire(key) ⇒ Object

Update the expiry_cache to notify other processes that the rimcached object at this key has changed and must be refreshed.



47
48
49
50
51
52
# File 'lib/rimcache/store.rb', line 47

def expire(key)
  cached[key] = nil
  reload_expiry(force: true)
  @expiry[key] = Time.current
  expiry_cache.write(config.expiry_cache_key, @expiry, expires_in: nil)
end

#expired?(key) ⇒ Boolean

Returns true if no value has been cached for key yet, if expire has been called from any process with access to the same expiry_cache

Returns:

  • (Boolean)

    Whether the value under key needs to be refreshed.



36
37
38
39
40
41
42
43
# File 'lib/rimcache/store.rb', line 36

def expired?(key)
  last_update = @written_at[key]
  return true if !cached[key] || needs_refresh?(last_update)

  # Check if another process has changed the value since we read it
  expired_at = reload_expiry[key]
  !!expired_at && expired_at > last_update
end

#fetch(key, for_update: false) ⇒ Object

Fetches or updates data from the rimcache at the given key. If there’s an unexpired stored value it is returned. Otherwise, the block is called and the result is frozen, stored in the rimcache under this key, and returned.

The keyword argument for_update can be set to true to call the block and return the result unfrozen instead of caching it. You must still call expire(key) or update(key, value) after updating the record in the database.

Raises:

  • (ArgumentError)


63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rimcache/store.rb', line 63

def fetch(key, for_update: false)
  raise(ArgumentError, "Rimcache: tried to store to cache with nil key") if key.nil?

  if for_update
    cached[key] = nil
    yield
  elsif expired?(key) || !cached[key]
    write(key, yield.freeze) if block_given?
  else
    read(key)
  end
end

#read(key) ⇒ Object

Returns the value cached under key



29
30
31
# File 'lib/rimcache/store.rb', line 29

def read(key)
  cached[key]
end

#update(key, value) ⇒ Object

Expires the rimcache for this key and saves a frozen clone of value as the new value.



78
79
80
81
# File 'lib/rimcache/store.rb', line 78

def update(key, value)
  expire(key)
  write(key, value.clone.freeze)
end