On Feb 25, 2011, at 11:24 AM, Brice Figureau wrote:

> On 25/02/11 18:29, Markus Roberts wrote:
>> 
>>    There's also a 3rd thing I didn't started working on: allow the code to
>>    set probes dynamically (instead of statistically adding them by
>>    modifying puppet code). I don't know if ruby versatility can allow this,
>>    but I'd love to be able to instance_eval { ... add probes around a
>>    method ... } to a given live puppet instance/class fully dynamically
>>    (that would be completely crazy).
>> 
>> 
>> This is in fact fairly easy to do, though you're right that it's
>> completely crazy.  :)
>> 
>> Suppose we have an array x and we want to do something with it's length
>> (negate it here, but presumably we'd be doing something more useful like
>> recording it or something):
>> 
>> irb(main)> x = [1,2,3]
>> => [1,2,3]
>> irb(main)> unless x.respond_to? :brice_wrapped_length
>> irb(main)>   class <<x
>> irb(main)>     alias brice_wrapped_length length
>> irb(main)>     def length
>> irb(main)>       -brice_wrapped_length
>> irb(main)>     end
>> irb(main)>   end
>> irb(main)> end
>> => nil
>> irb(main)> x.length
>> => -3
>> irb(main)> x << :foo
>> => [1, 2, 3, :foo]
>> irb(main)> x.length
>> => -4
>> 
>> Note that this only affects the one object; other arrays aren't touched:
>> 
>> irb(main)> y = [:a,:b]
>> [:a,:b]
>> irb(main)> y.length
>> 2
>> 
>> The unless part is important to prevent instrumenting the same object
>> twice, which will cause it to hang (and eventually stack overflow).  To
>> remove the instrumentation, just reverse everything (if instead of
>> unless, alias the other way, and then remove brice_wrapped_length).
> 
> Thanks for the example. This is quite interesting and opens the door to
> a lot of strange things :)
> 
> I was thinking about allowing the user to describe probes by specifying
> a puppet class and a method through an indirection to control probes
> (like in "Puppet::Indirector::Indirection.find"), then I'd do something
> (completely untested):
> 
> method = "find"
> klass_name = "Puppet::Indirector::Indirection"
> require klass_name.split('::').map { |n| n.downcase }.join('/')
> 
> klass = klass_name.split('::').inject(Puppet) { |p,c| p.const_get(c) }
> klass.class_eval do
>  alias "instr_#{method}" method
>  define_method(method, *args) do
>    # here call to instrumentation
>    send("instr_#{method}", args)
>  ensure
>   # here wrap up instrumentation
>  end
> end
> 
> Then I hope, somewhere else, someone calling Puppet::Something.find
> (provided Something uses the indirector of course), then it would call
> my programmatic redifinition of "find"...
> 
> This will be a funny week-end if that proves to work :)

I think this basic model is sound, and is roughly what I'd do.

You could also have a builtin system to allow classes to specify which methods 
should normally be probed.  E.g., create a module that essentially does this:

module Probable
  PROBABLE_CLASSES = []

  class Probe
    def initialize(method, klass, type)
    ...
    end
    def enable
      ...do the alias method switcheroo here
    end
  end
  def define_probe(name, type = :time)
    @probes << probe.new(name, self.class, type)
    PROBABLE_CLASSES << self.class
  end

  def self.enable_probes
    PROBABLE_CLASSES.each do |klass|
      klass.probes.each { |probe| probe.enable }
    end
  end
end

Obviously not really a great design per se, but as a general idea, it would 
allow any class to define what were most likely to be the appropriate probes, 
so that turning probes on for the system should result in the best data.  I 
like the idea of being able to manually enable probes through your command-line 
interface ideas, too, but I think the system should ship with a bunch of these 
out of the box.

-- 
Brand's Shortcut:
   The only way to predict the future is to make sure it stays
   exactly the same as the present.
---------------------------------------------------------------------
Luke Kanies  -|-   http://puppetlabs.com   -|-   +1(615)594-8199




-- 
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