~nvalcarcel/ubuntu/lucid/puppet/fix-546677

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-23 00:48:10 UTC
  • mfrom: (1.1.10 upstream) (3.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091223004810-3i4oryds922g5n59
Tags: 0.25.1-3ubuntu1
* Merge from debian testing.  Remaining changes:
  - debian/rules:
    + Don't start puppet when first installing puppet.
  - debian/puppet.conf, lib/puppet/defaults.rb:
    + Move templates to /etc/puppet
  - lib/puppet/defaults.rb:
    + Fix /var/lib/puppet/state ownership.
  - man/man8/puppet.conf.8: 
    + Fix broken URL in manpage.
  - debian/control:
    + Update maintainer accordint to spec.
    + Puppetmaster Recommends -> Suggests
    + Created puppet-testsuite as a seperate. Allow the users to run puppet's 
      testsuite.
  - tests/Rakefile: Fix rakefile so that the testsuite can acutally be ran.

Show diffs side-by-side

added added

removed removed

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