class Flor::Ganger
ganger | ˈɡaNGər | \ noun British \ the foreman of a gang of laborers.
The ganger receives the tasks from the flor executor, decides what tasker will be invoked and hands it the task.
Attributes
RESERVED_NAMES = %w[ tag ]
Public Class Methods
Public Instance Methods
Source
# File lib/flor/unit/ganger.rb, line 32 def has_tasker?(exid, name) #return false if RESERVED_NAMES.include?(name) d = Flor.domain(exid) !! ( @unit.loader.tasker(d, 'ganger') || @unit.loader.tasker(d, 'tasker') || @unit.loader.tasker(d, name)) end
Used by flor when it looks up for a variable and finds nothing. The last step is to ask the ganger if it knows about a tasker under the given (domain and) name.
If it returns true, flor knows there is a tasker under that name.
Source
# File lib/flor/unit/ganger.rb, line 95 def return(message) @unit.return(message) end
Called by the tasker implementations when they’re done with a task and want to hand it back to flor. It might be a failure message.
Source
# File lib/flor/unit/ganger.rb, line 47 def task(executor, message) domain = message['exid'].split('-', 2).first #tname = message['tasker'] tname = determine_tasker_name(executor, message) tconf = ( ! message['routed'] && (@unit.loader.tasker(domain, 'ganger', message) || @unit.loader.tasker(domain, 'tasker', message))) || @unit.loader.tasker(domain, tname, message) fail ArgumentError.new( "tasker #{tname.inspect} not found" ) unless tconf if tconf.is_a?(Array) points = [ nil, message['point'] ] points << 'detask' if points.include?('cancel') points << 'task' if points.include?('return') tconf = tconf.find { |h| points.include?(h['point']) } end fail ArgumentError.new( "tconf #{tconf.inspect} not a hash" ) unless tconf.is_a?(Hash) message['tconf'] = tconf unless tconf['include_tconf'] == false message['vars'] = gather_vars(executor, tconf, message) m = Flor.dup_message(message) # # the tasker gets a copy of the message (and it can play with it # to its heart content), meanwhile the message is handed to the # "post" notifiers. @unit.caller.call(self, tconf, m) # # might return a re-routing message, # especially if it's a domain tasker end
Called by Flor::Scheduler
. The ganger then has to hand the task (the message) to the proper tasker.
Protected Instance Methods
Source
# File lib/flor/unit/ganger.rb, line 157 def determine_tasker_name(executor, message) tname = message['tasker'] return tname if tname n = executor.node(message) n['task']['tasker'] end
Source
# File lib/flor/unit/ganger.rb, line 108 def expand_filter(f) return f unless f.is_a?(Array) f.collect { |e| if e.is_a?(String) e elsif e.is_a?(Array) && e[0] == '_rxs' && e[1].is_a?(String) s = e[1] li, ri = s.index('/'), s.rindex('/') tail = s[ri + 1..-1] ops = (tail.index('i') ? Regexp::IGNORECASE : 0) | (tail.index('x') ? Regexp::EXTENDED : 0) Regexp.new(s[li + 1..ri - 1], ops) else nil end }.compact end
Source
# File lib/flor/unit/ganger.rb, line 134 def gather_vars(executor, tconf, message) # try to return before a potentially costly call to executor.vars(nid) return nil if (tconf.keys & %w[ include_vars exclude_vars ]).empty? # default behaviour, don't pass variables to taskers iv = expand_filter(tconf['include_vars']) return nil if iv == false ev = expand_filter(tconf['exclude_vars']) return {} if ev == true vars = executor.vars(message['nid']) return vars if iv == true vars = vars.select { |k, v| var_match(k, iv) } if iv vars = vars.reject { |k, v| var_match(k, ev) } if ev vars end
By default, taskers don’t see the flor variables in the execution. If ‘include_vars’ or ‘exclude_vars’ is present in the configuration of the tasker, some or all of the variables are passed.
Source
# File lib/flor/unit/ganger.rb, line 102 def var_match(k, filter) filter.each { |f| return true if (f.is_a?(String) ? k == f : f.match(k)) } false end