~ubuntu-branches/ubuntu/trusty/puppet/trusty

« back to all changes in this revision

Viewing changes to lib/puppet/util/cacher.rb

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2011-10-22 14:08:22 UTC
  • mfrom: (1.1.25) (3.1.32 sid)
  • Revision ID: package-import@ubuntu.com-20111022140822-odxde5lohc45yhuz
Tags: 2.7.6-1
* New upstream release (CVE-2011-3872)
* Remove cherry-picked "groupadd_aix_warning" patch
* Install all new manpages

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
require 'monitor'
2
2
 
3
3
module Puppet::Util::Cacher
4
 
  module Expirer
5
 
    attr_reader :timestamp
6
 
 
7
 
    # Cause all cached values to be considered expired.
8
 
    def expire
9
 
      @timestamp = Time.now
10
 
    end
11
 
 
12
 
    # Is the provided timestamp earlier than our expiration timestamp?
13
 
    # If it is, then the associated value is expired.
14
 
    def dependent_data_expired?(ts)
15
 
      return false unless timestamp
16
 
 
17
 
      timestamp > ts
18
 
    end
19
 
  end
20
 
 
21
 
  extend Expirer
22
 
 
23
4
  # Our module has been extended in a class; we can only add the Instance methods,
24
5
  # which become *class* methods in the class.
25
6
  def self.extended(other)
40
21
  module ClassMethods
41
22
    # Provide a means of defining an attribute whose value will be cached.
42
23
    # Must provide a block capable of defining the value if it's flushed..
43
 
    def cached_attr(name, options = {}, &block)
 
24
    def cached_attr(name, ttl, &block)
44
25
      init_method = "init_#{name}"
45
26
      define_method(init_method, &block)
46
27
 
 
28
      set_attr_ttl(name, ttl)
 
29
 
47
30
      define_method(name) do
48
31
        cached_value(name)
49
32
      end
50
33
 
51
34
      define_method(name.to_s + "=") do |value|
52
35
        # Make sure the cache timestamp is set
53
 
        cache_timestamp
54
 
        value_cache.synchronize { value_cache[name] = value }
55
 
      end
56
 
 
57
 
      if ttl = options[:ttl]
58
 
        set_attr_ttl(name, ttl)
 
36
        value_cache.synchronize do
 
37
          value_cache[name] = value
 
38
          set_expiration(name)
 
39
        end
59
40
      end
60
41
    end
61
42
 
62
43
    def attr_ttl(name)
63
 
      return nil unless @attr_ttls
64
44
      @attr_ttls[name]
65
45
    end
66
46
 
72
52
 
73
53
  # Methods that get added to instances.
74
54
  module InstanceMethods
75
 
 
76
 
    def expire
77
 
      # Only expire if we have an expirer.  This is
78
 
      # mostly so that we can comfortably handle cases
79
 
      # like Puppet::Type instances, which use their
80
 
      # catalog as their expirer, and they often don't
81
 
      # have a catalog.
82
 
      if e = expirer
83
 
        e.expire
84
 
      end
85
 
    end
86
 
 
87
 
    def expirer
88
 
      Puppet::Util::Cacher
89
 
    end
90
 
 
91
55
    private
92
56
 
93
 
    def cache_timestamp
94
 
      @cache_timestamp ||= Time.now
95
 
    end
96
 
 
97
57
    def cached_value(name)
98
58
      value_cache.synchronize do
99
 
        # Allow a nil expirer, in which case we regenerate the value every time.
100
 
        if expired_by_expirer?(name)
101
 
          value_cache.clear
102
 
          @cache_timestamp = Time.now
103
 
        elsif expired_by_ttl?(name)
104
 
          value_cache.delete(name)
 
59
        if value_cache[name].nil? or expired_by_ttl?(name)
 
60
          value_cache[name] = send("init_#{name}")
 
61
          set_expiration(name)
105
62
        end
106
 
        value_cache[name] = send("init_#{name}") unless value_cache.include?(name)
107
63
        value_cache[name]
108
64
      end
109
65
    end
110
66
 
111
 
    def expired_by_expirer?(name)
112
 
      if expirer.nil?
113
 
        return true unless self.class.attr_ttl(name)
114
 
      end
115
 
      expirer.dependent_data_expired?(cache_timestamp)
116
 
    end
117
 
 
118
67
    def expired_by_ttl?(name)
119
 
      return false unless self.class.respond_to?(:attr_ttl)
120
 
      return false unless ttl = self.class.attr_ttl(name)
121
 
 
122
 
      @ttl_timestamps ||= {}
123
 
      @ttl_timestamps[name] ||= Time.now
124
 
 
125
 
      (Time.now - @ttl_timestamps[name]) > ttl
 
68
      @attr_expirations[name] < Time.now
 
69
    end
 
70
 
 
71
    def set_expiration(name)
 
72
      @attr_expirations ||= {}
 
73
      @attr_expirations[name] = Time.now + self.class.attr_ttl(name)
126
74
    end
127
75
 
128
76
    def value_cache