Module: CachedSingleton

Defined in:
lib/cached_singleton/version.rb,
lib/cached_singleton/cached_singleton.rb

Constant Summary collapse

VERSION =
'0.0.2'
@@cache_strategy =
nil

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_cache_strategyObject



10
11
12
13
14
15
# File 'lib/cached_singleton/cached_singleton.rb', line 10

def self.default_cache_strategy
  unless @@cache_strategy
    raise RuntimeError.new('default cache strategy not set')
  end
  @@cache_strategy
end

.default_cache_strategy=(cache_strategy) ⇒ Object



6
7
8
# File 'lib/cached_singleton/cached_singleton.rb', line 6

def self.default_cache_strategy=(cache_strategy)
  @@cache_strategy = cache_strategy
end

.included(model) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/cached_singleton/cached_singleton.rb', line 17

def self.included(model)
  model.class_eval do

    class << self
      def cache
        CachedSingleton.default_cache_strategy
      end

      def singleton_cache_key
        "/#{self.name}"
      end

      def instance
        # Fetch in cache
        m = self.cache.read(singleton_cache_key)
        return m if m

        # Get it in from the DB or create it
        transaction do
          # We ensure no other process is trying to SELECT OR INSERT the same record by locking
          # the entire table (read + write) during the transaction
          connection.execute("LOCK TABLE #{table_name} IN EXCLUSIVE MODE")
          m = first || create
        end

        # Save it in cache if it's in the DB
        self.cache.write(singleton_cache_key, m) if m.try(:persisted?)

        m
      end
    end

    after_commit :expire_cache
  end
end

Instance Method Details

#expire_cacheObject



53
54
55
# File 'lib/cached_singleton/cached_singleton.rb', line 53

def expire_cache
  self.class.cache.delete(self.class.singleton_cache_key) if (!new_record? || destroyed?)
end