class Flor::Node
Constants
- PROC_VAR_CONTAINER
- TASKER_VAR_CONTAINER
Attributes
message[R]
Public Class Methods
new(executor, node, message)
click to toggle source
# File lib/flor/core/node.rb, line 59 def initialize(executor, node, message) @executor, @execution = case executor when nil then [ nil, nil ] # for some tests when Hash then [ nil, executor ] # from some other tests else [ executor, executor.execution ] # vanilla case end @node = if node node elsif message @execution['nodes'][message['nid']] else nil end @message = message end
Public Instance Methods
child_id()
click to toggle source
# File lib/flor/core/node.rb, line 86 def child_id; Flor.child_id(@node['nid']); end
cnodes()
click to toggle source
# File lib/flor/core/node.rb, line 93 def cnodes; @node['cnodes']; end
cnodes_any?()
click to toggle source
# File lib/flor/core/node.rb, line 94 def cnodes_any?; cnodes && cnodes.any?; end
cnodes_empty?()
click to toggle source
# File lib/flor/core/node.rb, line 95 def cnodes_empty?; cnodes.nil? || cnodes.empty?; end
deref(s)
click to toggle source
Returns the referenced tree. Returns nil if not found.
# File lib/flor/core/node.rb, line 202 def deref(s) v = lookup_value(s) if Flor.is_tree?(v) ref = case v[0] when '_func' then true when '_proc' then v[1]['proc'] != s when '_tasker' then v[1]['tasker'] != s else false end v[1]['oref'] ||= v[1]['ref'] if ref && v[1]['ref'] v[1]['ref'] = s if ref v else [ '_val', v, tree[2] ] end rescue KeyError => ke nil end
descendant_of?(nid, on_self=true)
click to toggle source
# File lib/flor/core/node.rb, line 258 def descendant_of?(nid, on_self=true) return on_self if self.nid == nid && on_self != nil i = self.nid loop do node = @executor.node(i) break unless node i = node['parent'] return true if i == nid end false end
domain()
click to toggle source
# File lib/flor/core/node.rb, line 88 def domain; Flor.domain(@execution['exid']); end
exid()
click to toggle source
# File lib/flor/core/node.rb, line 82 def exid; @execution['exid']; end
fei()
click to toggle source
# File lib/flor/core/node.rb, line 248 def fei "#{exid}-#{nid}" end
from()
click to toggle source
# File lib/flor/core/node.rb, line 91 def from; @from || @message['from']; end
h()
click to toggle source
# File lib/flor/core/node.rb, line 80 def h; @node; end
lookup_tree(nid)
click to toggle source
# File lib/flor/core/node.rb, line 132 def lookup_tree(nid) return nil unless nid node = @execution['nodes'][nid] tree = node && node['tree'] return tree if tree par = node && node['parent'] cid = Flor.child_id(nid) tree = par && lookup_tree(par) return subtree(tree, par, nid) if tree return nil if node tree = lookup_tree(Flor.parent_nid(nid)) return tree[1][cid] if tree #tree = lookup_tree(Flor.parent_nid(nid, remove_subnid=true)) #return tree[1][cid] if tree # # might become necessary at some point nil end
lookup_value(path)
click to toggle source
# File lib/flor/core/node.rb, line 160 def lookup_value(path) original_path = path path = case path when '*' then [ path ] when String then Dense::Path.make(path).to_a else path end path.unshift('v') \ if path.length < 2 case path.first when /\Af(?:ld|ield)?\z/ lookup_field(nil, path[1..-1]) # mod -> nil... when /\At(?:ag)?\z/ lookup_tag(nil, path[1]) when /\A([lgd]?)v(?:ar|ariable)?\z/ return @message['__head'][1] if path[1] == '__head' lookup_var(@node, $1, path[1], path[2..-1]) when 'node' lookup_in_node(path[1..-1]) when 'exe', 'execution' lookup_in_execution(path[1..-1]) else lookup_var(@node, '', path[0], path[1..-1]) end rescue KeyError => ke class << ke; attr_accessor :original_path, :work_path; end ke.original_path = original_path ke.work_path = path raise end
message_or_node_payload()
click to toggle source
# File lib/flor/core/node.rb, line 128 def message_or_node_payload payload.current ? payload : node_payload end
nid()
click to toggle source
# File lib/flor/core/node.rb, line 83 def nid; @node['nid']; end
node_closed?()
click to toggle source
# File lib/flor/core/node.rb, line 107 def node_closed? node_status['status'] == 'closed' end
node_ended?()
click to toggle source
# File lib/flor/core/node.rb, line 110 def node_ended? node_status['status'] == 'ended' end
node_open?()
click to toggle source
# File lib/flor/core/node.rb, line 113 def node_open? node_status['status'] == nil end
node_payload()
click to toggle source
# File lib/flor/core/node.rb, line 117 def node_payload @node_payload ||= Payload.new(self) end
node_payload_ret()
click to toggle source
# File lib/flor/core/node.rb, line 120 def node_payload_ret Flor.dup(node_payload['ret']) end
node_status()
click to toggle source
# File lib/flor/core/node.rb, line 101 def node_status @node['status'].last end
node_status_flavour()
click to toggle source
# File lib/flor/core/node.rb, line 104 def node_status_flavour node_status['flavour'] end
on_error_parent(skip=false)
click to toggle source
# File lib/flor/core/node.rb, line 274 def on_error_parent(skip=false) if @node['in_on_error'] # prevent loop when error in on_error: skip = true end if (@node['on_error'] || []).find { |criteria, _| match_on?(criteria) } return self unless skip skip = false end if pn = parent_node return Flor::Node.new(@executor, pn, @message).on_error_parent(skip) end nil end
parent()
click to toggle source
# File lib/flor/core/node.rb, line 84 def parent; @node['parent']; end
payload()
click to toggle source
# File lib/flor/core/node.rb, line 97 def payload @message_payload ||= Payload.new(self, :message) end
payload_ret()
click to toggle source
# File lib/flor/core/node.rb, line 124 def payload_ret message['payload']['ret'] end
point()
click to toggle source
# File lib/flor/core/node.rb, line 90 def point; @message['point']; end
reheap(tree, heat)
click to toggle source
# File lib/flor/core/node.rb, line 231 def reheap(tree, heat) case when ! heat.is_a?(Array) then '_val' when tree && tree[1] == [] then '_val' when heat[0] == '_proc' then heat[1]['proc'] when heat[0] == '_func' then 'apply' when heat[0] == '_tasker' then 'task' else '_val' end end
to_procedure_node()
click to toggle source
# File lib/flor/core/node.rb, line 253 def to_procedure_node Flor::Procedure.new(@executor, @node, @message) end
tree()
click to toggle source
# File lib/flor/core/node.rb, line 243 def tree lookup_tree(nid) end
Protected Instance Methods
escape(k)
click to toggle source
# File lib/flor/core/node.rb, line 374 def escape(k) case k when '*', '.' then "\\#{k}" else k end end
extract_on_info()
click to toggle source
# File lib/flor/core/node.rb, line 531 def extract_on_info kla = @message['error']['kla'] msg = @message['error']['msg'] la = kla.split('::').last [ kla, la, msg ] end
is_ancestor_node?(node_or_nid, node=@node)
click to toggle source
Returns true if the current node has the node identified with nid as an ancestor. Returns false else.
# File lib/flor/core/node.rb, line 330 def is_ancestor_node?(node_or_nid, node=@node) nid = node_or_nid return false unless nid nid = node_or_nid['nid'] unless nid.is_a?(String) return false unless node return true if node['nid'] == nid is_ancestor_node?(nid, parent_node(node)) end
lookup_arg_container(key)
click to toggle source
# File lib/flor/core/node.rb, line 483 def lookup_arg_container(key) vars = lookup_var_container(@node, '', 'arguments') return {} unless vars args = vars['arguments'] return {} unless args val = case key when 'arga', 'args', 'argv' then args.collect(&:last) else args.inject({}) { |h, (k, v)| h[k] = v if k; h } end { key => val } end
lookup_dvar_container(mod, key)
click to toggle source
# File lib/flor/core/node.rb, line 462 def lookup_dvar_container(mod, key) if mod != 'd' && Flor::Procedure[key] return PROC_VAR_CONTAINER end l = @executor.unit.loader vdomain = @node['vdomain'] # if l && vdomain != false vars = l.variables(vdomain || domain) return vars if vars.has_key?(key) end if mod != 'd' && @executor.unit.has_tasker?(@executor.exid, key) return TASKER_VAR_CONTAINER end {} end
lookup_field(mod, key_and_path)
click to toggle source
# File lib/flor/core/node.rb, line 511 def lookup_field(mod, key_and_path) Dense.fetch(payload.current, key_and_path) end
lookup_in_execution(path)
click to toggle source
# File lib/flor/core/node.rb, line 353 def lookup_in_execution(path) if path == %w[ domain ] Flor.domain(@execution['exid']) else Dense.fetch(@execution, path) end end
lookup_in_node(path)
click to toggle source
def closure_node(node=@node)
@execution['nodes'][node['cnid']]
end
# File lib/flor/core/node.rb, line 348 def lookup_in_node(path) Dense.fetch(@node, path) end
lookup_tag(mod, key)
click to toggle source
# File lib/flor/core/node.rb, line 500 def lookup_tag(mod, key) nids = @execution['nodes'].inject([]) do |a, (nid, n)| a << nid if n['tags'] && n['tags'].include?(key) a end nids.any? ? nids : nil end
lookup_var(node, mod, key, pth)
click to toggle source
# File lib/flor/core/node.rb, line 382 def lookup_var(node, mod, key, pth) c = lookup_var_container(node, mod, key) kp = [ key, pth ].reject { |x| x == nil || x.size < 1 }.join('.') kp = escape(kp) Dense.fetch(c, kp) rescue KeyError => ke m = "variable #{ke.miss[3].inspect} not found" m += " at #{Dense::Path.make(ke.miss[1]).to_s.inspect}" if ke.miss[1].any? raise ke.relabel(m) rescue IndexError => ie m = if ie.miss[1] == [ ie.miss[2] ] "variable #{ie.miss[2].inspect} not found" else pa = Dense::Path.make(ie.miss[1]).to_s.inspect ty = Flor.type(ie.miss[2]) ke = ie.miss[3].inspect "variable at #{pa} is a #{ty}, it has no key #{ke}" end raise ie.relabel(m) #rescue TypeError => te # leave as is end
lookup_var_container(node, mod, key)
click to toggle source
# File lib/flor/core/node.rb, line 426 def lookup_var_container(node, mod, key) return lookup_dvar_container(mod, key) \ if node == nil || mod == 'd' return lookup_arg_container(key) \ if mod == '' && %w[ arga args argv argh argd ].include?(key) if vwl = node['vwlist'] # variable white list return lookup_dvar_container(mod, key) unless var_match?(vwl, key) end if vbl = node['vblist'] # variable black list return lookup_dvar_container(mod, key) if var_match?(vbl, key) end pnode = parent_node(node) vars = node['vars'] if mod == 'g' return lookup_var_container(pnode, mod, key) if pnode return vars if vars fail "node #{node['nid']} has no vars and no parent" end return vars if vars && vars.has_key?(key) if cnid = node['cnid'] cvars = (@execution['nodes'][cnid] || {})['vars'] return cvars if cvars && cvars.has_key?(key) end # # look into closure, just one level deep... lookup_var_container(pnode, mod, key) end
match_on?(criteria)
click to toggle source
Return true if the current @message matches on the given array of criteria.
# File lib/flor/core/node.rb, line 519 def match_on?(criteria) # AND, not OR, hence the true at the bottom criteria .each { |c| next if c == '*' return false unless send("match_on_#{c[0]}?", c) } true end
match_on_class?(criterion)
click to toggle source
# File lib/flor/core/node.rb, line 540 def match_on_class?(criterion) c1 = criterion[1] kla, la, _ = extract_on_info kla == c1 || la == c1 end
match_on_regex?(criterion)
click to toggle source
# File lib/flor/core/node.rb, line 556 def match_on_regex?(criterion) c1 = Flor.to_regex(criterion) kla, _, msg = extract_on_info msg =~ c1 || kla =~ c1 end
match_on_string?(criterion)
click to toggle source
# File lib/flor/core/node.rb, line 548 def match_on_string?(criterion) c1 = criterion[1] kla, la, msg = extract_on_info msg == c1 || kla == c1 || la == c1 end
parent_node(node=@node)
click to toggle source
# File lib/flor/core/node.rb, line 312 def parent_node(node=@node) @execution['nodes'][node['parent']] end
parent_node_procedure(node=@node)
click to toggle source
# File lib/flor/core/node.rb, line 322 def parent_node_procedure(node=@node) Flor::Procedure.make(@executor, parent_node(node), @message) end
parent_node_tree(node=@node)
click to toggle source
# File lib/flor/core/node.rb, line 317 def parent_node_tree(node=@node) lookup_tree(node['parent']) end
subtree(tree, pnid, nid)
click to toggle source
# File lib/flor/core/node.rb, line 294 def subtree(tree, pnid, nid) pnid = Flor.master_nid(pnid) nid = Flor.master_nid(nid) return nil unless nid[0, pnid.length] == pnid # maybe failing would be better cid = nid[pnid.length + 1..-1] return nil unless cid # maybe failing would be better cid.split('_').each { |id| tree = tree[1][id.to_i] } tree end
var_match?(vs, key)
click to toggle source
# File lib/flor/core/node.rb, line 415 def var_match?(vs, key) vs.each do |v| return true if v == key return true if v.is_a?(Regexp) && v =~ key # TODO fun call end false end