Mange / roadie
1
# frozen_string_literal: true
2

3 5
module Roadie
4
  # @api public
5
  # The {CachedProvider} wraps another provider (or {ProviderList}) and caches
6
  # the response from it.
7
  #
8
  # The default cache store is a instance-specific hash that lives for the
9
  # entire duration of the instance. If you want to share hash between
10
  # instances, pass your own hash-like object. Just remember to not allow this
11
  # cache to grow without bounds, which a shared hash would do.
12
  #
13
  # Not found assets are not cached currently, but it's possible to extend this
14
  # class in the future if there is a need for it. Remember this if you have
15
  # providers with very slow failures.
16
  #
17
  # The cache store must accept {Roadie::Stylesheet} instances, and return such
18
  # instances when fetched. It must respond to `#[name]` and `#[name]=` to
19
  # retrieve and set entries, respectively. The `#[name]=` method also needs to
20
  # return the instance again.
21
  #
22
  # @example Global cache
23
  #   Application.asset_cache = Hash.new
24
  #   slow_provider = MyDatabaseProvider.new(Application)
25
  #   provider = Roadie::CachedProvider.new(slow_provider, Application.asset_cache)
26
  #
27
  # @example Custom cache store
28
  #   class MyRoadieMemcacheStore
29
  #     def initialize(memcache)
30
  #       @memcache = memcache
31
  #     end
32
  #
33
  #     def [](path)
34
  #       css = memcache.read("assets/#{path}/css")
35
  #       if css
36
  #         name = memcache.read("assets/#{path}/name") || "cached #{path}"
37
  #         Roadie::Stylesheet.new(name, css)
38
  #       end
39
  #     end
40
  #
41
  #     def []=(path, stylesheet)
42
  #       memcache.write("assets/#{path}/css", stylesheet.to_s)
43
  #       memcache.write("assets/#{path}/name", stylesheet.name)
44
  #       stylesheet # You need to return the set Stylesheet
45
  #     end
46
  #   end
47
  #
48 5
  class CachedProvider
49
    # The cache store used by this instance.
50 5
    attr_reader :cache
51

52
    # @param upstream [an asset provider] The wrapped asset provider
53
    # @param cache [#[], #[]=] The cache store to use.
54 5
    def initialize(upstream, cache = {})
55 5
      @upstream = upstream
56 5
      @cache = cache
57
    end
58

59 5
    def find_stylesheet(name)
60 5
      cache_fetch(name) do
61 5
        @upstream.find_stylesheet(name)
62
      end
63
    end
64

65 5
    def find_stylesheet!(name)
66 5
      cache_fetch(name) do
67 5
        @upstream.find_stylesheet!(name)
68
      end
69
    end
70

71 5
    private
72 5
    def cache_fetch(name)
73 5
      cache[name] || cache[name] = yield
74
    rescue CssNotFound
75 5
      cache[name] = nil
76 5
      raise
77
    end
78
  end
79
end

Read our documentation on viewing source code .

Loading