Class: Card::Cache::Persistent

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

Overview

Persistent (or Hard) caches closely mirror the database and are intended to be altered only upon database alterations.

Unlike the database, the persistent cache stores records of records that have been requested but are missing or, in the case of some cards, "virtual", meaning that they follow known patterns but do not exist in the database.

Most persistent cache implementations cannot store objects with singleton classes, therefore cards generally must have set_modules re-included after retrieval from the persistent cache.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Persistent

Returns a new instance of Persistent.

Parameters:

  • opts (Hash)

Options Hash (opts):

  • :store (Rails::Cache)
  • :class, (ruby Class)

    typically ActiveRecord descendant

  • :database (String)


57
58
59
60
61
62
# File 'lib/card/cache/persistent.rb', line 57

def initialize opts
  @store = opts[:store]
  @klass = opts[:class]
  @class_key = @klass.to_s.to_name.key
  @database = opts[:database] || self.class.database_name
end

Instance Attribute Details

#prefixObject

prefix added to cache key to create a system-wide unique key



98
99
100
# File 'lib/card/cache/persistent.rb', line 98

def prefix
  @prefix
end

Class Method Details

.database_nameObject

name of current database; used here to insure that different databases are cached separately TODO: find better home for this method



24
25
26
27
28
# File 'lib/card/cache/persistent.rb', line 24

def database_name
  @database_name ||= (cfg = Cardio.config) &&
                     (dbcfg = cfg.database_configuration) &&
                     dbcfg[Rails.env]["database"]
end

.new_stampObject

stamp generator



35
36
37
# File 'lib/card/cache/persistent.rb', line 35

def new_stamp
  Time.now.to_i.to_s(36) + rand(999).to_s(36)
end

.renewObject



43
44
45
# File 'lib/card/cache/persistent.rb', line 43

def renew
  @stamp = nil
end

.resetObject



47
48
49
50
# File 'lib/card/cache/persistent.rb', line 47

def reset
  @stamp = new_stamp
  Cardio.cache.write stamp_key, @stamp
end

.stampObject



30
31
32
# File 'lib/card/cache/persistent.rb', line 30

def stamp
  @stamp ||= Cardio.cache.fetch(stamp_key) { new_stamp }
end

.stamp_keyObject



39
40
41
# File 'lib/card/cache/persistent.rb', line 39

def stamp_key
  "#{database_name}-stamp"
end

Instance Method Details

#annihilateObject

the nuclear option. can affect other applications sharing the same cache engine. keep in mind mutually assured destruction.



81
82
83
# File 'lib/card/cache/persistent.rb', line 81

def annihilate
  @store.clear
end

#deep_read(key) ⇒ Object



126
127
128
129
130
# File 'lib/card/cache/persistent.rb', line 126

def deep_read key
  local_cache = @store.send :local_cache
  local_cache&.clear
  read key
end

#delete(key) ⇒ Object



145
146
147
# File 'lib/card/cache/persistent.rb', line 145

def delete key
  @store.delete full_key(key)
end

#exist?(key) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/card/cache/persistent.rb', line 149

def exist? key
  @store.exist? full_key(key)
end

#fetch(key, &block) ⇒ Object



141
142
143
# File 'lib/card/cache/persistent.rb', line 141

def fetch key, &block
  @store.fetch full_key(key), &block
end

#full_key(key) ⇒ String

returns prefix/key

Parameters:

  • key (String)

Returns:

  • (String)


105
106
107
# File 'lib/card/cache/persistent.rb', line 105

def full_key key
  "#{prefix}/#{key}"
end

#read(key) ⇒ Object



109
110
111
# File 'lib/card/cache/persistent.rb', line 109

def read key
  @store.read full_key(key)
end

#read_attribute(key, attribute) ⇒ Object



132
133
134
135
# File 'lib/card/cache/persistent.rb', line 132

def read_attribute key, attribute
  object = deep_read key
  object.instance_variable_get "@#{attribute}"
end

#renewObject

renew insures you're using the most current cache version by reaffirming the stamp and prefix



66
67
68
69
# File 'lib/card/cache/persistent.rb', line 66

def renew
  @stamp = nil
  @prefix = nil
end

#resetObject

reset effectively clears the cache by setting a new stamp. However unlike annihilate, it won't bother other apps using the same cache engine.



73
74
75
76
77
# File 'lib/card/cache/persistent.rb', line 73

def reset
  @stamp = self.class.new_stamp
  @prefix = nil
  Cardio.cache.write stamp_key, @stamp
end

#stampObject

the current time stamp. changing this value effectively resets the cache. Note that Cardio.cache is a simple Rails::Cache, not a Card::Cache object.



88
89
90
# File 'lib/card/cache/persistent.rb', line 88

def stamp
  @stamp ||= Cardio.cache.fetch(stamp_key) { self.class.new_stamp }
end

#stamp_keyObject

key for looking up the current stamp



93
94
95
# File 'lib/card/cache/persistent.rb', line 93

def stamp_key
  "#{@database}-#{@class_key}-#{self.class.stamp}-stamp"
end

#write(key, value) ⇒ Object



137
138
139
# File 'lib/card/cache/persistent.rb', line 137

def write key, value
  @store.write full_key(key), value
end

#write_attribute(key, attribute, value) ⇒ Object

update an attribute of an object already in the cache

Parameters:

  • key (String)
  • attribute (String, Symbol)


116
117
118
119
120
121
122
123
124
# File 'lib/card/cache/persistent.rb', line 116

def write_attribute key, attribute, value
  return value unless @store

  if (object = deep_read key)
    object.instance_variable_set "@#{attribute}", value
    write key, object
  end
  value
end