flor 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +9 -0
  3. data/CREDITS.md +21 -0
  4. data/LICENSE.txt +4 -1
  5. data/Makefile +4 -0
  6. data/README.md +8 -0
  7. data/flor.gemspec +10 -10
  8. data/lib/flor.rb +2 -2
  9. data/lib/flor/changes.rb +3 -3
  10. data/lib/flor/colours.rb +14 -8
  11. data/lib/flor/conf.rb +63 -58
  12. data/lib/flor/core.rb +4 -4
  13. data/lib/flor/core/executor.rb +65 -29
  14. data/lib/flor/core/node.rb +37 -20
  15. data/lib/flor/core/procedure.rb +182 -40
  16. data/lib/flor/core/texecutor.rb +125 -52
  17. data/lib/flor/djan.rb +111 -82
  18. data/lib/flor/dollar.rb +31 -30
  19. data/lib/flor/flor.rb +314 -237
  20. data/lib/flor/id.rb +7 -2
  21. data/lib/flor/log.rb +250 -245
  22. data/lib/flor/parser.rb +72 -38
  23. data/lib/flor/pcore/_arr.rb +10 -10
  24. data/lib/flor/pcore/_att.rb +49 -14
  25. data/lib/flor/pcore/_coll.rb +18 -0
  26. data/lib/flor/pcore/_obj.rb +23 -7
  27. data/lib/flor/pcore/_pat_.rb +1 -1
  28. data/lib/flor/pcore/_pat_guard.rb +8 -0
  29. data/lib/flor/pcore/_pat_obj.rb +3 -3
  30. data/lib/flor/pcore/_pat_or.rb +4 -0
  31. data/lib/flor/pcore/_pat_regex.rb +24 -0
  32. data/lib/flor/pcore/_skip.rb +4 -0
  33. data/lib/flor/pcore/_val.rb +0 -1
  34. data/lib/flor/pcore/all.rb +111 -0
  35. data/lib/flor/pcore/any.rb +83 -0
  36. data/lib/flor/pcore/arith.rb +35 -6
  37. data/lib/flor/pcore/break.rb +39 -1
  38. data/lib/flor/pcore/case.rb +82 -4
  39. data/lib/flor/pcore/cmp.rb +7 -7
  40. data/lib/flor/pcore/collect.rb +50 -0
  41. data/lib/flor/pcore/cond.rb +17 -3
  42. data/lib/flor/pcore/cursor.rb +8 -2
  43. data/lib/flor/pcore/detect.rb +45 -0
  44. data/lib/flor/pcore/each.rb +52 -0
  45. data/lib/flor/pcore/empty.rb +60 -0
  46. data/lib/flor/pcore/filter.rb +94 -0
  47. data/lib/flor/pcore/find.rb +67 -0
  48. data/lib/flor/pcore/for_each.rb +65 -0
  49. data/lib/flor/pcore/includes.rb +32 -0
  50. data/lib/flor/pcore/inject.rb +55 -0
  51. data/lib/flor/pcore/iterator.rb +151 -0
  52. data/lib/flor/pcore/keys.rb +60 -0
  53. data/lib/flor/pcore/length.rb +34 -7
  54. data/lib/flor/pcore/logo.rb +18 -0
  55. data/lib/flor/pcore/loop.rb +4 -0
  56. data/lib/flor/pcore/map.rb +77 -46
  57. data/lib/flor/pcore/match.rb +8 -2
  58. data/lib/flor/pcore/matchr.rb +4 -5
  59. data/lib/flor/pcore/move.rb +3 -3
  60. data/lib/flor/pcore/noeval.rb +13 -0
  61. data/lib/flor/pcore/not.rb +16 -0
  62. data/lib/flor/pcore/on.rb +172 -0
  63. data/lib/flor/pcore/on_cancel.rb +54 -0
  64. data/lib/flor/pcore/on_error.rb +68 -0
  65. data/lib/flor/pcore/rand.rb +2 -2
  66. data/lib/flor/pcore/range.rb +2 -1
  67. data/lib/flor/pcore/reduce.rb +124 -0
  68. data/lib/flor/pcore/reverse.rb +46 -0
  69. data/lib/flor/pcore/select.rb +72 -0
  70. data/lib/flor/pcore/set.rb +8 -0
  71. data/lib/flor/pcore/stall.rb +10 -0
  72. data/lib/flor/pcore/to_array.rb +61 -0
  73. data/lib/flor/pcore/until.rb +34 -0
  74. data/lib/flor/punit/cancel.rb +30 -5
  75. data/lib/flor/punit/ccollect.rb +11 -0
  76. data/lib/flor/punit/cmap.rb +10 -5
  77. data/lib/flor/punit/concurrence.rb +42 -51
  78. data/lib/flor/punit/cron.rb +33 -0
  79. data/lib/flor/punit/do_trap.rb +42 -0
  80. data/lib/flor/punit/every.rb +48 -13
  81. data/lib/flor/punit/graft.rb +3 -3
  82. data/lib/flor/punit/on_timeout.rb +38 -0
  83. data/lib/flor/punit/schedule.rb +69 -6
  84. data/lib/flor/punit/signal.rb +54 -0
  85. data/lib/flor/punit/sleep.rb +1 -1
  86. data/lib/flor/punit/task.rb +4 -1
  87. data/lib/flor/punit/trap.rb +188 -13
  88. data/lib/flor/tools/shell.rb +408 -62
  89. data/lib/flor/tools/shell_out.rb +31 -0
  90. data/lib/flor/unit.rb +1 -1
  91. data/lib/flor/unit/caller.rb +177 -0
  92. data/lib/flor/unit/executor.rb +1 -0
  93. data/lib/flor/unit/ganger.rb +15 -21
  94. data/lib/flor/unit/hook.rb +1 -1
  95. data/lib/flor/unit/hooker.rb +22 -10
  96. data/lib/flor/unit/loader.rb +22 -22
  97. data/lib/flor/unit/logger.rb +63 -36
  98. data/lib/flor/unit/models.rb +6 -1
  99. data/lib/flor/unit/models/execution.rb +12 -1
  100. data/lib/flor/unit/models/message.rb +7 -0
  101. data/lib/flor/unit/models/trap.rb +31 -17
  102. data/lib/flor/unit/scheduler.rb +18 -10
  103. data/lib/flor/unit/storage.rb +83 -23
  104. data/lib/flor/unit/waiter.rb +1 -2
  105. metadata +96 -52
  106. data/lib/flor/deep.rb +0 -144
  107. data/lib/flor/punit/on.rb +0 -57
  108. data/lib/flor/unit/runner.rb +0 -84
  109. data/match.md +0 -22
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5d8fca99889bde91b7433d98d674f44c810c041421ce61eef1857e80930e8cef
4
+ data.tar.gz: 7a06654dbe17ac06aa3afeab0a04b9958851bdaf393df0d48f994dae4681c072
5
+ SHA512:
6
+ metadata.gz: 0a17e80b8bf6207bd3688f2c57172a51ac471c5f3beaf28803ff8ce41587dc6b181b5295b041dbfa586e6556ee045be56553164e6b09183745c0cfd2562d8c0c
7
+ data.tar.gz: fad82fa8619af8623b6312d6a4f234f5433d71edcbd05964367c8cde547be357f08d77e9c0e99078f2c71cbf74bfbf7691cae62025f53ce7537ad91cb0ef4d74
@@ -2,6 +2,15 @@
2
2
  # flor CHANGELOG.md
3
3
 
4
4
 
5
+ ## flor 0.15.0 released 2018-06-15
6
+
7
+ - Many many improvements
8
+ - Implement "cron" (macro for "schedule cron:")
9
+ - Introduce Flor.point?(s)
10
+ - Archive terminated, failed and ceased messages (Tsunehisa Doi)
11
+ - Let "case" match regular expressions
12
+
13
+
5
14
  ## flor 0.14.0 released 2017-06-13
6
15
 
7
16
  - Implement "match"
@@ -0,0 +1,21 @@
1
+
2
+ # CREDITS.md
3
+
4
+ ## Contributors
5
+
6
+ * David Verrier - https://github.com/dverrier
7
+ * Tsunehisa Doi - https://github.com/dmicky0419
8
+ * Jean-François Rioux - https://github.com/jfrioux
9
+ * Danny Fullerton - https://github.com/northox
10
+ * John Mettraux - https://github.com/jmettraux
11
+
12
+ https://github.com/floraison/flor/graphs/contributors
13
+
14
+ ## Feedback
15
+
16
+ ## ruote legacy
17
+
18
+ Many thanks to all the ruote contributors.
19
+
20
+ https://github.com/jmettraux/ruote/blob/30a6bb88a4e48ed2e1b9089754f1c8be8c1a879c/CREDITS.txt
21
+
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
2
+ Copyright (c) 2015-2018, John Mettraux, jmettraux+flor@gmail.com
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
19
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  THE SOFTWARE.
21
21
 
22
+
23
+ Made in Japan
24
+
data/Makefile CHANGED
@@ -8,6 +8,7 @@ VERSION = \
8
8
 
9
9
  count_lines:
10
10
  find lib -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
11
+ find spec -name "*_spec.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
11
12
  cl: count_lines
12
13
 
13
14
  gemspec_validate:
@@ -68,6 +69,8 @@ mk:
68
69
 
69
70
  doc:
70
71
  $(RUBY) -Imak -r 'doc' -e "make_procedures_doc()"
72
+ doct:
73
+ @$(RUBY) mak/ptree.rb
71
74
 
72
75
  shell:
73
76
  $(RUBY) -Ilib -r 'flor/tools/shell' -e 'Flor::Tools::Shell.new'
@@ -76,6 +79,7 @@ sh: shell
76
79
  cleanshell:
77
80
  rm -f envs/shell/var/flor.db
78
81
  rm -fR envs/shell/var/tasks/*
82
+ rm -f .log.txt
79
83
 
80
84
  .PHONY: doc shell cleanshell
81
85
 
data/README.md CHANGED
@@ -8,6 +8,7 @@ Flor is a "Ruby workflow engine", if that makes any sense.
8
8
 
9
9
  * [![Join the chat at https://gitter.im/floraison/flor](https://badges.gitter.im/floraison/flor.svg)](https://gitter.im/floraison/flor?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
10
10
  * [floraison mailing list](https://groups.google.com/forum/#!forum/floraison)
11
+ * [twitter.com/@flor_workflow](https://twitter.com/flor_workflow)
11
12
 
12
13
  ## Design
13
14
 
@@ -29,6 +30,13 @@ See [quickstart/](quickstart/).
29
30
 
30
31
  See [doc/](doc/).
31
32
 
33
+ ## blog posts and presentations
34
+
35
+ * [Flor, hubristic interpreter](http://rubykaigi.org/2017/presentations/jmettraux.html) - RubyKaigi 2017, Hiroshima - presentation
36
+ * [flor design 0](http://jmettraux.skepti.ch/20171021.html?t=flor_design_0) - running a simple execution, what happens - blog post
37
+ * [flor, branch to branch](https://speakerdeck.com/jmettraux/flor-branch-to-branch) - q1 2017 - very dry deck
38
+ * [flor 2017](https://speakerdeck.com/jmettraux/flor-2017) - q1 2017 - very dry deck
39
+
32
40
 
33
41
  ## LICENSE
34
42
 
@@ -21,22 +21,22 @@ A Ruby workflow engine (ruote next generation)
21
21
 
22
22
  #s.files = `git ls-files`.split("\n")
23
23
  s.files = Dir[
24
+ 'README.{md,txt}',
25
+ 'CHANGELOG.{md,txt}', 'CREDITS.{md,txt}', 'LICENSE.{md,txt}',
24
26
  'Makefile',
25
27
  'lib/**/*.rb', #'spec/**/*.rb', 'test/**/*.rb',
26
- '*.gemspec', '*.txt', '*.rdoc', '*.md'
28
+ "#{s.name}.gemspec",
27
29
  ]
28
30
 
29
- s.add_runtime_dependency 'munemo', '>= 1.0.1'
30
- s.add_runtime_dependency 'raabro', '>= 1.1.3'
31
- #s.add_runtime_dependency 'rufus-lru', '>= 1.1.0'
32
- s.add_runtime_dependency 'fugit', '>= 0.9.5'
31
+ s.add_runtime_dependency 'munemo', '~> 1.0', '>= 1.0.1'
32
+ s.add_runtime_dependency 'raabro', '~> 1.1', '>= 1.1.5'
33
+ #s.add_runtime_dependency 'rufus-lru', '~> 1.1'
34
+ s.add_runtime_dependency 'fugit', '~> 1.1'
35
+ s.add_runtime_dependency 'dense', '~> 1.1', '>= 1.1.1'
33
36
 
34
- s.add_development_dependency 'sequel', '~> 4'
35
- #
36
- # flor in transient mode doesn't need a storage,
37
- # so Sequel is not a runtime dependency
37
+ s.add_runtime_dependency 'sequel', '~> 4'
38
38
 
39
- s.add_development_dependency 'rspec', '3.4.0'
39
+ s.add_development_dependency 'rspec', '~> 3.7'
40
40
  s.add_development_dependency 'terminal-table'
41
41
 
42
42
  s.require_path = 'lib'
@@ -8,11 +8,12 @@ require 'socket'
8
8
 
9
9
  require 'munemo'
10
10
  require 'raabro'
11
+ require 'dense'
11
12
 
12
13
 
13
14
  module Flor
14
15
 
15
- VERSION = '0.14.0'
16
+ VERSION = '0.15.0'
16
17
  end
17
18
 
18
19
  require 'flor/colours'
@@ -21,7 +22,6 @@ require 'flor/djan'
21
22
  require 'flor/id'
22
23
  require 'flor/log'
23
24
  require 'flor/flor'
24
- require 'flor/deep'
25
25
  require 'flor/dollar'
26
26
  require 'flor/errors'
27
27
  require 'flor/parser'
@@ -17,9 +17,9 @@ module Flor::Changes
17
17
  def do_apply(h, c)
18
18
 
19
19
  case c['op']
20
- when 'add' then Flor.deep_insert(h, c['path'], c['value'])
21
- when 'replace' then Flor.deep_set(h, c['path'], c['value'])
22
- when 'remove' then Flor.deep_unset(h, c['path'])
20
+ when 'add' then Dense.insert(h, c['path'], c['value'])
21
+ when 'replace' then Dense.set(h, c['path'], c['value'])
22
+ when 'remove' then Dense.unset(h, c['path'])
23
23
  end
24
24
  end
25
25
  end
@@ -58,23 +58,29 @@ module Flor
58
58
 
59
59
  def self.colours(opts={})
60
60
 
61
- c = nil
62
- #
63
- [ :color, :colour, :colors, :colours ].each do |k|
64
- if opts.has_key?(k); c = opts[k]; break; end
65
- end
61
+ #opts =
62
+ # case opts
63
+ # when Hash then opts
64
+ # when Colours, NoColours then { color: opts }
65
+ # else { out: opts }
66
+ # end
67
+
68
+ c = nil;
69
+ [ :color, :colour, :colors, :colours ].each do |k|
70
+ if opts.has_key?(k); c = opts[k]; break; end
71
+ end
66
72
 
67
73
  return @colours if c == true
68
74
  return @no_colours if c == false
69
75
 
70
76
  o = opts[:out] || $stdout
71
77
 
72
- col =
78
+ return @colours if (
73
79
  (o.respond_to?(:log_colours?) ? o.log_colours? : o.tty?) ||
74
80
  ($0[-6..-1] == '/rspec' &&
75
- (ARGV.include?('--tty') || ARGV.include?('--color')))
81
+ (ARGV.include?('--tty') || ARGV.include?('--color'))))
76
82
 
77
- col ? @colours : @no_colours
83
+ @no_colours
78
84
  end
79
85
 
80
86
  def self.decolour(s)
@@ -67,78 +67,83 @@ module Flor
67
67
  #
68
68
  # For example `debug: 'msg,stdout'`
69
69
 
70
- def self.prepare(conf, over_conf)
70
+ class << self
71
71
 
72
- c = conf
73
- c = Flor::ConfExecutor.interpret(c) if c.is_a?(String)
72
+ def prepare(conf, over_conf)
74
73
 
75
- fail ArgumentError.new(
76
- "cannot extract conf out of #{c.inspect} (#{conf.class})"
77
- ) unless c.is_a?(Hash)
74
+ c = conf
75
+ c = Flor::ConfExecutor.interpret_path_or_source(c) if c.is_a?(String)
78
76
 
79
- unless c['conf'] == true
80
- #
81
- # don't read FLOR_DEBUG if this executor is only meant to read the conf
77
+ fail ArgumentError.new(
78
+ "cannot extract conf out of #{c.inspect} (#{conf.class})"
79
+ ) unless c.is_a?(Hash)
82
80
 
83
- c.merge!(interpret_flor_debug(c))
84
- c.merge!(interpret_env)
85
- end
86
-
87
- c.merge!(over_conf)
88
- end
81
+ unless c['conf'] == true
82
+ #
83
+ # don't read FLOR_DEBUG if this executor is only meant to read
84
+ # the conf
89
85
 
90
- def self.get_class(conf, key)
86
+ c.merge!(interpret_flor_debug(c))
87
+ c.merge!(interpret_env)
88
+ end
91
89
 
92
- if v = conf[key]
93
- Flor.const_lookup(v)
94
- else
95
- nil
90
+ c.merge!(over_conf)
96
91
  end
97
- end
98
-
99
- protected # somehow
100
-
101
- LOG_DBG_KEYS = %w[ dbg msg err src tree tree_rw run ]
102
- LOG_ALL_KEYS = %w[ all log sto ] + LOG_DBG_KEYS
103
92
 
104
- def self.interpret_flor_debug(c)
93
+ def get_class(conf, key)
105
94
 
106
- plus, minus = [ c['flor_debug'], c['debug'], ENV['FLOR_DEBUG'] ]
107
- .collect { |v| (v || '').split(/\s*,\s*/) }
108
- .flatten(1)
109
- .partition { |v| v[0, 1] != '-' }
110
- plus = plus.collect { |v| v[0, 1] == '+' ? v[1..-1] : v }
111
- minus = minus.collect { |v| v[0, 1] == '-' ? v[1..-1] : v }
112
- a = plus - minus
113
-
114
- h =
115
- a.inject({}) { |h, kv|
116
- k, v = kv.split(':')
117
- k = 'sto' if k == 'db'
118
- k = "log_#{k}" if LOG_ALL_KEYS.include?(k)
119
- h[k] = v ? JSON.parse(v) : true
120
- h
121
- }
122
- LOG_ALL_KEYS.each { |k| h["log_#{k}"] = 1 } if h['log_all']
123
- LOG_DBG_KEYS.each { |k| h["log_#{k}"] = 1 } if h['log_dbg']
124
-
125
- h['log_colours'] = true \
126
- if a.include?('colours') || a.include?('colors')
127
- # LOG_DEBUG=colours forces colors
95
+ if v = conf[key]
96
+ Flor.const_lookup(v)
97
+ else
98
+ nil
99
+ end
100
+ end
128
101
 
129
- h['log_out'] = 'stdout' if h.delete('stdout')
130
- h['log_out'] = 'stderr' if h.delete('stderr')
102
+ LOG_DBG_KEYS = %w[ dbg msg err src tree tree_rw run ]
103
+ LOG_ALL_KEYS = %w[ all log sto ] + LOG_DBG_KEYS
104
+
105
+ def interpret_flor_debug(c)
106
+
107
+ plus, minus = [
108
+ c['flor_debug'], c[:debug], c['debug'], ENV['FLOR_DEBUG'] ]
109
+ .collect { |v| (v || '').split(/\s*,\s*/) }
110
+ .flatten(1)
111
+ .partition { |v| v[0, 1] != '-' }
112
+ plus = plus.collect { |v| v[0, 1] == '+' ? v[1..-1] : v }
113
+ minus = minus.collect { |v| v[0, 1] == '-' ? v[1..-1] : v }
114
+ a = plus - minus
115
+
116
+ h =
117
+ a.inject({}) { |h, kv|
118
+ k, v = kv.split(':')
119
+ k = 'sto' if k == 'db'
120
+ k = "log_#{k}" if LOG_ALL_KEYS.include?(k)
121
+ h[k] = v ? JSON.parse(v) : true
122
+ h
123
+ }
124
+ LOG_ALL_KEYS.each { |k| h["log_#{k}"] = 1 } if h['log_all']
125
+ LOG_DBG_KEYS.each { |k| h["log_#{k}"] = 1 } if h['log_dbg']
126
+
127
+ h['log_colours'] = true \
128
+ if a.include?('colours') || a.include?('colors')
129
+ # LOG_DEBUG=colours forces colors
130
+
131
+ h['log_out'] = 'stdout' if h.delete('stdout')
132
+ h['log_out'] = 'stderr' if h.delete('stderr')
133
+
134
+ h
135
+ end
131
136
 
132
- h
133
- end
137
+ protected
134
138
 
135
- def self.interpret_env
139
+ def interpret_env
136
140
 
137
- h = {}
138
- u = ENV['FLOR_UNIT']
139
- h['unit'] = u if u
141
+ h = {}
142
+ u = ENV['FLOR_UNIT']
143
+ h['unit'] = u if u
140
144
 
141
- h
145
+ h
146
+ end
142
147
  end
143
148
  end
144
149
  end
@@ -28,17 +28,17 @@ module Flor
28
28
 
29
29
  t =
30
30
  tree.is_a?(String) ?
31
- Flor::Lang.parse(tree, opts[:fname], opts) :
31
+ Flor.parse(tree, opts[:fname], opts) :
32
32
  tree
33
33
 
34
34
  unless t
35
35
 
36
36
  #h = opts.merge(prune: false, rewrite: false, debug: 0)
37
- #Raabro.pp(Flor::Lang.parse(tree, h[:fname], h))
37
+ #Raabro.pp(Flor.parse(tree, h[:fname], h))
38
38
  # TODO re-parse and indicate what went wrong...
39
39
 
40
40
  fail ArgumentError.new(
41
- "flor parse failure: " + tree.inspect[0, 35] + '...')
41
+ "flow parsing failed: " + tree.inspect[0, 35] + '...')
42
42
  end
43
43
 
44
44
  pl = opts[:payload] || opts[:fields] || {}
@@ -74,7 +74,7 @@ module Flor
74
74
  File.join(File.dirname(__FILE__), dir, '*.rb')
75
75
  end
76
76
 
77
- Dir[dirpath].each { |path| require(path) }
77
+ Dir[dirpath].sort.each { |path| require(path) }
78
78
  end
79
79
  end
80
80
 
@@ -85,7 +85,7 @@ module Flor
85
85
  # be lenient with block hooks, help them return an array
86
86
  end
87
87
 
88
- # Given a nid, returns a copy of all the var the node sees
88
+ # Given a nid, returns a copy of all the var the node sees at that point.
89
89
  #
90
90
  def vars(nid, vs={})
91
91
 
@@ -124,15 +124,15 @@ module Flor
124
124
 
125
125
  nid = message['nid']
126
126
 
127
- now = Flor.tstamp
127
+ n = Flor.tstamp
128
128
 
129
129
  node = {
130
130
  'nid' => nid,
131
131
  'parent' => message['from'],
132
132
  'payload' => message['payload'],
133
- 'status' => [ { 'status' => nil, 'point' => 'execute', 'ctime' => now } ],
134
- 'ctime' => now,
135
- 'mtime' => now }
133
+ 'status' => [ { 'status' => nil, 'point' => 'execute', 'ctime' => n } ],
134
+ 'ctime' => n,
135
+ 'mtime' => n }
136
136
 
137
137
  %w[ vars vdomain cnid dbg ].each do |k|
138
138
  v = message[k]
@@ -240,7 +240,16 @@ module Flor
240
240
 
241
241
  return [ head.rewrite ] if head.is_a?(Flor::Macro)
242
242
 
243
- head.send("do_#{message['point']}")
243
+ point = message['point']
244
+ point = 'kill' if message['flavour'] == 'kill'
245
+
246
+ messages = head.send("do_#{point}")
247
+
248
+ fail StandardError.new(
249
+ "#{heap}/#{message['point']} did not return an Array"
250
+ ) unless messages.is_a?(Array)
251
+
252
+ messages
244
253
  end
245
254
 
246
255
  def toc_messages(message)
@@ -250,6 +259,7 @@ module Flor
250
259
  m = message.select { |k, v| %w[ exid nid from payload ].include?(k) }
251
260
  m['sm'] = message['m']
252
261
  m['point'] = message['from'] == '0' ? 'terminated' : 'ceased'
262
+ m['cause'] = message['cause'] if message.has_key?('cause')
253
263
 
254
264
  [ m ]
255
265
  end
@@ -340,13 +350,11 @@ module Flor
340
350
 
341
351
  ts = node['tags']; return [] unless ts && ts.any?
342
352
 
343
- [
344
- { 'point' => 'left',
353
+ [ { 'point' => 'left',
345
354
  'tags' => ts,
346
355
  'exid' => exid,
347
356
  'nid' => node['nid'],
348
- 'payload' => message['payload'] }
349
- ]
357
+ 'payload' => message['payload'] } ]
350
358
  end
351
359
 
352
360
  def error_reply(node, message, err)
@@ -359,7 +367,6 @@ module Flor
359
367
  m['error'] = Flor.to_error(err)
360
368
 
361
369
  @unit.logger.log_err(self, m, flag: true)
362
- #Flor.print_detail_msg(self, m, flag: true) if @unit.conf['log_err']
363
370
 
364
371
  #if m['error']['msg'].match(/\AToo many open files in system/)
365
372
  # puts "=" * 80 + ' ...'
@@ -396,22 +403,43 @@ module Flor
396
403
  #
397
404
  # FIXME is it in use???
398
405
 
399
- [
400
- { 'point' => 'receive',
406
+ [ { 'point' => 'receive',
401
407
  'exid' => message['exid'],
402
408
  'nid' => message['nid'],
403
409
  'payload' => message['payload'],
404
- 'tasker' => message['tasker'] }
405
- ]
410
+ 'tasker' => message['tasker'] } ]
406
411
  end
407
412
 
408
413
  def cancel(message)
409
414
 
410
- if n = @execution['nodes'][message['nid']]
411
- apply(n, message)
412
- else
413
- [] # nothing, node gone
414
- end
415
+ n = @execution['nodes'][message['nid']]
416
+ return [] unless n # node gone
417
+
418
+ apply(n, message)
419
+ end
420
+
421
+ def stack_cause(message)
422
+
423
+ pt = message['point']
424
+ fl = message['flavour']
425
+
426
+ cause = pt # trigger or cancel
427
+ cause = fl if %w[ kill timeout ].include?(fl) # only for cancel, hopefully
428
+
429
+ last = (message['cause'] ||= [])[0]
430
+
431
+ c = {
432
+ 'cause' => cause,
433
+ 'm' => message['m'],
434
+ 'nid' => message['nid'],
435
+ 'type' => message['type'],
436
+ 'at' => last && last['at'] }
437
+
438
+ return if c == last
439
+
440
+ message['cause'] =
441
+ [ c.tap { |h| h['at'] = Flor.tstamp } ] +
442
+ message['cause']
415
443
  end
416
444
 
417
445
  def process(message)
@@ -421,6 +449,9 @@ module Flor
421
449
  message['m'] = counter_next('msgs') # number messages
422
450
  message['pr'] = counter('runs') # "processing run"
423
451
 
452
+ stack_cause(message) \
453
+ if %w[ trigger cancel ].include?(message['point'])
454
+
424
455
  determine_heat(message)
425
456
 
426
457
  ms = []
@@ -477,16 +508,21 @@ module Flor
477
508
  "node #{message['nid']} is gone, cannot flag it as failed"
478
509
  ) unless n
479
510
 
480
- #begin
481
511
  n['failure'] = Flor.dup(message)
482
- #rescue; pp message; exit 0; end
483
512
 
484
- oep = lookup_on_error_parent(message)
485
- return oep.trigger_on_error if oep
486
-
487
- @unit.logger.log_err(self, message)
488
-
489
- []
513
+ if oep = lookup_on_error_parent(message)
514
+ #
515
+ # There is a parent with an 'on_error', trigger it that parent
516
+ # with its 'on_error' turned on.
517
+ #
518
+ oep.trigger_on_error
519
+ else
520
+ #
521
+ # Simply log and don't add further messages ([]) to execute
522
+ #
523
+ @unit.logger.log_err(self, message)
524
+ []
525
+ end
490
526
  end
491
527
 
492
528
  def signal(message); []; end
@@ -494,7 +530,7 @@ module Flor
494
530
  def lookup_on_error_parent(message)
495
531
 
496
532
  nd = Flor::Node.new(self, nil, message).on_error_parent
497
- nd ? nd.to_procedure : nil
533
+ nd ? nd.to_procedure_node : nil
498
534
  end
499
535
  end
500
536
  end