class MCollective::Agents

A collection of agents, loads them, reloads them and dispatches messages to them. It uses the PluginManager to store, load and manage instances of plugins.

Public Class Methods

agentlist() click to toggle source

Get a list of agents that we have

# File lib/mcollective/agents.rb, line 123
def self.agentlist
    @@agents.keys
end
new() click to toggle source
# File lib/mcollective/agents.rb, line 5
def initialize
    @config = Config.instance
    raise ("Configuration has not been loaded, can't load agents") unless @config.configured

    @@agents = {}

    loadagents
end

Public Instance Methods

dispatch(msg, target, connection) { |replies| ... } click to toggle source

Dispatches a message to an agent, accepts a block that will get run if there are any replies to process from the agent

# File lib/mcollective/agents.rb, line 96
def dispatch(msg, target, connection)
    Log.debug("Dispatching a message to agent #{target}")

    Thread.new do
        begin
            agent = PluginManager["#{target}_agent"]

            Timeout::timeout(agent.timeout) do
                replies = agent.handlemsg(msg, connection)

                # Agents can decide if they wish to reply or not,
                # returning nil will mean nothing goes back to the
                # requestor
                unless replies == nil
                    yield(replies)
                end
            end
        rescue Timeout::Error => e
            Log.warn("Timeout while handling message for #{target}")
        rescue Exception => e
            Log.error("Execution of #{target} failed: #{e}")
            Log.error(e.backtrace.join("\n\t\t"))
        end
    end
end
findagentfile(agentname) click to toggle source

searches the libdirs for agents

# File lib/mcollective/agents.rb, line 62
def findagentfile(agentname)
    @config.libdir.each do |libdir|
        agentfile = "#{libdir}/mcollective/agent/#{agentname}.rb"
        if File.exist?(agentfile)
            Log.debug("Found #{agentname} at #{agentfile}")
            return agentfile
        end
    end
    return false
end
help(agentname) click to toggle source

Returns the help for an agent after first trying to get rid of some indentation infront

# File lib/mcollective/agents.rb, line 80
def help(agentname)
    raise("No such agent") unless include?(agentname)

    body = PluginManager["#{agentname}_agent"].help.split("\n")

    if body.first =~ %r^(\s+)\S/
        indent = $1

        body = body.map {|b| b.gsub(%r^#{indent}/, "")}
    end

    body.join("\n")
end
include?(agentname) click to toggle source

Determines if we have an agent with a certain name

# File lib/mcollective/agents.rb, line 74
def include?(agentname)
    PluginManager.include?("#{agentname}_agent")
end
loadagent(agentname) click to toggle source

Loads a specified agent from disk if available

# File lib/mcollective/agents.rb, line 38
def loadagent(agentname)
    agentfile = findagentfile(agentname)
    return false unless agentfile
    classname = "MCollective::Agent::#{agentname.capitalize}"

    PluginManager.delete("#{agentname}_agent")

    begin
        single_instance = ["registration", "discovery"].include?(agentname)

        PluginManager.loadclass(classname)
        PluginManager << {:type => "#{agentname}_agent", :class => classname, :single_instance => single_instance}

        Util.subscribe(Util.make_target(agentname, :command)) unless @@agents.include?(agentname)

        @@agents[agentname] = {:file => agentfile}
        return true
    rescue Exception => e
        Log.error("Loading agent #{agentname} failed: #{e}")
        PluginManager.delete("#{agentname}_agent")
    end
end
loadagents() click to toggle source

Loads all agents from disk

# File lib/mcollective/agents.rb, line 15
def loadagents
    Log.debug("Reloading all agents from disk")

    # We're loading all agents so just nuke all the old agents and unsubscribe
    @@agents.each_key do |agent|
        PluginManager.delete "#{agent}_agent"
        Util.unsubscribe(Util.make_target(agent, :command))
    end

    @@agents = {}

    @config.libdir.each do |libdir|
        agentdir = "#{libdir}/mcollective/agent"
        next unless File.directory?(agentdir)

        Dir.new(agentdir).grep(%r\.rb$/).each do |agent|
            agentname = File.basename(agent, ".rb")
            loadagent(agentname) unless PluginManager.include?("#{agentname}_agent")
        end
    end
end