File: cache.rb

package info (click to toggle)
ruby-ramaze 2012.12.08-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,060 kB
  • ctags: 1,200
  • sloc: ruby: 10,446; makefile: 8
file content (121 lines) | stat: -rw-r--r-- 3,715 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#          Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
# All files in this distribution are subject to the terms of the MIT license.

module Ramaze
  module Helper
    ##
    # Caching of simple objects and whole action responses.
    #
    module Cache
      # Setup needed traits, add the singleton methods and add the caches used
      # by this helper.
      #
      # @param [Class] into Class that this Module is included into
      # @author manveru
      #
      def self.included(into)
        into.extend(SingletonMethods)
        into.add_action_wrapper(6.0, :cache_wrap)
        into.trait[:cache_action] ||= Set.new
        Ramaze::Cache.add(:action, :cache_helper_value)
      end

      ##
      # @param [Action] action The currently wrapped action
      # @yield The next block in wrap_action_call
      # @return [String] the response body
      # @see Innate::Node#wrap_action_call
      # @author manveru
      #
      def cache_wrap(action)
        cache = Innate::Cache.action

        ancestral_trait[:cache_action].each do |cache_action|
          temp  = cache_action.dup
          block = temp.delete(:key)
          ttl   = temp.delete(:ttl)

          if temp.all?{|key, value| action[key] == value }
            cache_key = action.full_path
            cache_key << "_#{action.instance.instance_eval(&block).to_s}" if block

            if cached = cache[cache_key]
              action.options[:content_type] = cached[:type]
            else
              cached = {
                :body => catch(:respond) { yield },
                :type => response['Content-Type']
              }

              if ttl
                cache.store(cache_key, cached, :ttl => ttl)
              else
                cache.store(cache_key, cached)
              end
            end

            return cached[:body]
          end
        end

        yield
      end

      ##
      # This method is used to access Ramaze::Cache.cache_helper_value.
      # It provides an easy way to cache long-running computations, gathering
      # external resources like RSS feeds or DB queries that are the same for
      # every user of an application.
      # This method changes behaviour if a block is passed, which can be used
      # to do lazy computation of the cached value conveniently when using a
      # custom TTL or longer expressions that don't fit on one line with ||=.
      #
      # @example to get the cache object directly
      #
      #   count = cache_value[:count] ||= Article.count
      #
      # @example with block
      #
      #   count = cache_value(:count){ Article.count }
      #   count = cache_value(:count, :ttl => 60){ Article.count }
      #
      # @return [Object] The cache wrapper assigned for :cache_helper_value
      # @see Innate::Cache
      # @author manveru
      #
      def cache_value(key = nil, options = {})
        cache = Ramaze::Cache.cache_helper_value

        if key and block_given?
          if found = cache[key]
            found
          else
            cache.store(key, yield, options)
          end
        else
          cache
        end
      end

      module SingletonMethods
        # This method allows you to cache whole actions.
        #
        # @example Basic usage
        #   class Foo < Ramaze::Controller
        #     helper :cache
        #     cache_action :method => :bar
        #
        #     def bar
        #       rand
        #     end
        #   end
        #
        def cache_action(hash, &block)
          hash[:key] = block if block_given?
          hash[:method] = hash[:method].to_s
          trait[:cache_action] << hash
        end
      end
    end # Cache
  end # Helper
end # Ramaze