On Oct 15, 2008, at 6:46 PM, Sean E. Millichamp wrote:

>
> On Wed, 2008-10-15 at 14:54 -0500, Luke Kanies wrote:
>
>> If you're going to use class variables (or really, anything that gets
>> cached between transactions) you need to flush the variables between
>> transactions.
>>
>> It might be as easy as setting a ttl on the cached values -- never
>> return values older than 0.5 of the runinterval, for instance.
>>
>> You definitely don't want to just have a single value and stick with
>> it for the life of a process, though.
>>
>> You probably also need some way to invalidate that cache when a file
>> gets changed.
>>
>> You might want to look at util/cacher.rb in the master branch -- it'd
>> be straightforward to backport it.
>
> Ahh, great point... I hadn't considered the long-running process
> scenario.  Thus far I've only done minimal experiments with running
> Puppet as a daemon and usually do one-shot runs.
>
> I'll take a look at util/cacher.rb, but I like the ttl approach too.
>
> I knew that fix seemed too easy.... :)
>
> Thanks for the review.


All the Cacher module does is provide a global timestamp, where values  
generated before that time are considered invalid.

It solves a bit of a different problem -- I was having issues where I  
needed to reset systems back to their defaults, mostly for testing  
(e.g., if I change a setting during an integration test, then I have a  
(possibly later) unit test that verifies the setting's default)

You should be able to pretty easily build a system that's similar to  
the Cacher module, but instead of using this global timestamp, it just  
uses a ttl.  You'd need to differentiate between defining and  
retrieving the value, like Cacher does.

For instance, here's an example of a Cacher-cached attribute:

     # Use cached termini.
     def termini
         attr_cache(:termini) { Hash.new }
     end

If the currently cached hash is newer than that global timestamp, then  
the current value is returned, otherwise the provided block is called  
and its result is used to provide the new value, which is both cached  
and returned.

Der, I realize now that Cacher could do this in one method call:

   cached_attr(:termini) { Hash.new }

To flush this cached value, you call Puppet::Util::Cacher.invalidate.   
In other words, we're using a single, global timestamp to determine  
whether a bunch of other global values need to be recalculated.  I  
considered making the timestamp class-specific, but for my needs  
(testing) what I really wanted was the global cache flush, and this  
single global timestamp ended up being really easy.

So, for your needs, you'd want something similar, but with the ability  
to specify a ttl.  In fact, you might even want to just refactor  
Cacher to support an optional ttl:

   cached_attr(:termini, :ttl => 300) { Hash.new }

This would guarantee that the value would never live longer than 5  
minutes, but the cache could also be flushed through the global  
Cacher.invalidate method used to refresh the timestamp.

So, you'd do something like:

   cached_attr(:selinux_actual_context, :ttl =>  
Puppet[:runinterval].to_i / 2) { Hash.new }
   cached_attr(:selinux_default_context, :ttl =>  
Puppet[:runinterval].to_i / 2) { Hash.new }

The point here is to just create a new hash if the cache gets flushed.

Then, to use it, you just do:

if selinux_actual_context.hash_key? "foo"
   ...
end

Of course, you'd actually want these attributes to be class level, so  
you'd do 'if self.class.selinux_actual_context....' (I don't remember  
the details, but it might be that the Cacher doesn't do class methods  
very well?).

If that's not clear, feel free to ask for elaboration.  I'll also make  
a quick pass at adding comments to the Cacher module.

-- 
Most people are born and years later die without really having lived
at all. They play it safe and tiptoe through life with no aspiration
other than to arrive at death safely. -- Tony Campolo, "Carpe Diem"
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to