flor 0.17.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +48 -0
  3. data/CREDITS.md +1 -0
  4. data/LICENSE.txt +1 -1
  5. data/Makefile +1 -1
  6. data/README.md +34 -2
  7. data/flor.gemspec +8 -9
  8. data/lib/flor.rb +3 -2
  9. data/lib/flor/colours.rb +5 -3
  10. data/lib/flor/conf.rb +1 -0
  11. data/lib/flor/core.rb +9 -8
  12. data/lib/flor/core/executor.rb +25 -22
  13. data/lib/flor/core/node.rb +1 -13
  14. data/lib/flor/core/procedure.rb +57 -12
  15. data/lib/flor/core/texecutor.rb +35 -3
  16. data/lib/flor/djan.rb +1 -0
  17. data/lib/flor/errors.rb +1 -0
  18. data/lib/flor/flor.rb +173 -29
  19. data/lib/flor/id.rb +5 -1
  20. data/lib/flor/log.rb +20 -8
  21. data/lib/flor/migrations/0001_tables.rb +1 -0
  22. data/lib/flor/migrations/0002_cunit_and_munit.rb +1 -0
  23. data/lib/flor/migrations/0003_timer_onid_bnid.rb +1 -0
  24. data/lib/flor/migrations/0004_trap_bnid.rb +1 -0
  25. data/lib/flor/migrations/0005_pointer_content.rb +1 -0
  26. data/lib/flor/parser.rb +19 -11
  27. data/lib/flor/pcore/_apply.rb +1 -0
  28. data/lib/flor/pcore/_arr.rb +1 -0
  29. data/lib/flor/pcore/_atom.rb +1 -0
  30. data/lib/flor/pcore/_att.rb +1 -0
  31. data/lib/flor/pcore/_coll.rb +1 -0
  32. data/lib/flor/pcore/_dmute.rb +5 -1
  33. data/lib/flor/pcore/_dol.rb +1 -0
  34. data/lib/flor/pcore/_dqs.rb +1 -0
  35. data/lib/flor/pcore/_dump.rb +1 -0
  36. data/lib/flor/pcore/_err.rb +1 -0
  37. data/lib/flor/pcore/_head.rb +1 -0
  38. data/lib/flor/pcore/_obj.rb +1 -0
  39. data/lib/flor/pcore/_pat_.rb +1 -0
  40. data/lib/flor/pcore/_pat_arr.rb +1 -0
  41. data/lib/flor/pcore/_pat_guard.rb +1 -0
  42. data/lib/flor/pcore/_pat_obj.rb +1 -0
  43. data/lib/flor/pcore/_pat_or.rb +1 -0
  44. data/lib/flor/pcore/_pat_regex.rb +1 -0
  45. data/lib/flor/pcore/_ref.rb +1 -0
  46. data/lib/flor/pcore/_rxs.rb +1 -0
  47. data/lib/flor/pcore/_skip.rb +1 -0
  48. data/lib/flor/pcore/_val.rb +1 -0
  49. data/lib/flor/pcore/all.rb +1 -0
  50. data/lib/flor/pcore/andor.rb +1 -0
  51. data/lib/flor/pcore/any.rb +1 -0
  52. data/lib/flor/pcore/apply.rb +1 -0
  53. data/lib/flor/pcore/arith.rb +1 -0
  54. data/lib/flor/pcore/array_qmark.rb +1 -0
  55. data/lib/flor/pcore/break.rb +13 -1
  56. data/lib/flor/pcore/case.rb +1 -0
  57. data/lib/flor/pcore/cmp.rb +1 -0
  58. data/lib/flor/pcore/collect.rb +2 -1
  59. data/lib/flor/pcore/cond.rb +1 -0
  60. data/lib/flor/pcore/cursor.rb +45 -3
  61. data/lib/flor/pcore/define.rb +1 -0
  62. data/lib/flor/pcore/detect.rb +1 -0
  63. data/lib/flor/pcore/do_return.rb +1 -0
  64. data/lib/flor/pcore/each.rb +1 -0
  65. data/lib/flor/pcore/echo.rb +1 -0
  66. data/lib/flor/pcore/empty.rb +1 -0
  67. data/lib/flor/pcore/fail.rb +1 -0
  68. data/lib/flor/pcore/filter.rb +1 -0
  69. data/lib/flor/pcore/find.rb +1 -0
  70. data/lib/flor/pcore/flatten.rb +1 -0
  71. data/lib/flor/pcore/for_each.rb +1 -0
  72. data/lib/flor/pcore/if.rb +1 -0
  73. data/lib/flor/pcore/includes.rb +1 -0
  74. data/lib/flor/pcore/inject.rb +1 -0
  75. data/lib/flor/pcore/iterator.rb +1 -0
  76. data/lib/flor/pcore/keys.rb +1 -0
  77. data/lib/flor/pcore/length.rb +1 -0
  78. data/lib/flor/pcore/loop.rb +1 -0
  79. data/lib/flor/pcore/map.rb +1 -0
  80. data/lib/flor/pcore/match.rb +1 -0
  81. data/lib/flor/pcore/matchr.rb +1 -0
  82. data/lib/flor/pcore/max.rb +1 -0
  83. data/lib/flor/pcore/merge.rb +1 -0
  84. data/lib/flor/pcore/move.rb +1 -0
  85. data/lib/flor/pcore/noeval.rb +1 -0
  86. data/lib/flor/pcore/noret.rb +1 -0
  87. data/lib/flor/pcore/not.rb +1 -0
  88. data/lib/flor/pcore/on.rb +34 -9
  89. data/lib/flor/pcore/on_cancel.rb +1 -0
  90. data/lib/flor/pcore/on_error.rb +1 -0
  91. data/lib/flor/pcore/push.rb +1 -0
  92. data/lib/flor/pcore/rand.rb +1 -0
  93. data/lib/flor/pcore/range.rb +1 -0
  94. data/lib/flor/pcore/reduce.rb +1 -0
  95. data/lib/flor/pcore/return.rb +1 -0
  96. data/lib/flor/pcore/reverse.rb +1 -0
  97. data/lib/flor/pcore/select.rb +1 -0
  98. data/lib/flor/pcore/sequence.rb +49 -0
  99. data/lib/flor/pcore/set.rb +1 -0
  100. data/lib/flor/pcore/shuffle.rb +1 -0
  101. data/lib/flor/pcore/slice.rb +1 -0
  102. data/lib/flor/pcore/sort.rb +1 -0
  103. data/lib/flor/pcore/sort_by.rb +1 -0
  104. data/lib/flor/pcore/split.rb +1 -0
  105. data/lib/flor/pcore/stall.rb +1 -0
  106. data/lib/flor/pcore/strings.rb +1 -0
  107. data/lib/flor/pcore/timestamp.rb +1 -0
  108. data/lib/flor/pcore/to_array.rb +1 -0
  109. data/lib/flor/pcore/twig.rb +1 -0
  110. data/lib/flor/pcore/type_of.rb +1 -0
  111. data/lib/flor/pcore/until.rb +1 -0
  112. data/lib/flor/punit/abort.rb +50 -0
  113. data/lib/flor/punit/c_collect.rb +1 -0
  114. data/lib/flor/punit/c_each.rb +19 -0
  115. data/lib/flor/punit/c_for_each.rb +2 -1
  116. data/lib/flor/punit/c_iterator.rb +2 -1
  117. data/lib/flor/punit/c_map.rb +1 -0
  118. data/lib/flor/punit/cancel.rb +10 -1
  119. data/lib/flor/punit/concurrence.rb +7 -5
  120. data/lib/flor/punit/cron.rb +1 -0
  121. data/lib/flor/punit/do_trap.rb +1 -0
  122. data/lib/flor/punit/every.rb +1 -0
  123. data/lib/flor/punit/graft.rb +1 -0
  124. data/lib/flor/punit/{m_ram.rb → m_receive_and_merge.rb} +5 -4
  125. data/lib/flor/punit/on_timeout.rb +1 -0
  126. data/lib/flor/punit/part.rb +1 -0
  127. data/lib/flor/punit/schedule.rb +1 -0
  128. data/lib/flor/punit/signal.rb +30 -5
  129. data/lib/flor/punit/sleep.rb +1 -0
  130. data/lib/flor/punit/task.rb +9 -2
  131. data/lib/flor/punit/trace.rb +1 -0
  132. data/lib/flor/punit/trap.rb +41 -1
  133. data/lib/flor/to_string.rb +1 -0
  134. data/lib/flor/tools/env.rb +1 -0
  135. data/lib/flor/tools/firb.rb +33 -0
  136. data/lib/flor/tools/shell.rb +13 -3
  137. data/lib/flor/tools/shell_out.rb +1 -0
  138. data/lib/flor/tt.rb +98 -0
  139. data/lib/flor/unit.rb +3 -0
  140. data/lib/flor/unit/caller.rb +158 -23
  141. data/lib/flor/unit/caller_jruby.rb +133 -0
  142. data/lib/flor/unit/dump.rb +36 -0
  143. data/lib/flor/unit/executor.rb +28 -18
  144. data/lib/flor/unit/ganger.rb +30 -18
  145. data/lib/flor/unit/gangers.rb +125 -0
  146. data/lib/flor/unit/hloader.rb +34 -7
  147. data/lib/flor/unit/hook.rb +3 -0
  148. data/lib/flor/unit/hooker.rb +32 -15
  149. data/lib/flor/unit/journal.rb +23 -0
  150. data/lib/flor/unit/loader.rb +142 -15
  151. data/lib/flor/unit/logger.rb +35 -7
  152. data/lib/flor/unit/models.rb +48 -10
  153. data/lib/flor/unit/models/execution.rb +51 -0
  154. data/lib/flor/unit/models/message.rb +6 -0
  155. data/lib/flor/unit/models/pointer.rb +1 -0
  156. data/lib/flor/unit/models/timer.rb +1 -0
  157. data/lib/flor/unit/models/trace.rb +1 -0
  158. data/lib/flor/unit/models/trap.rb +15 -6
  159. data/lib/flor/unit/scheduler.rb +211 -61
  160. data/lib/flor/unit/spooler.rb +1 -0
  161. data/lib/flor/unit/storage.rb +117 -73
  162. data/lib/flor/unit/taskers.rb +115 -1
  163. data/lib/flor/unit/waiter.rb +22 -17
  164. data/lib/flor/unit/wlist.rb +19 -8
  165. metadata +26 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bf01d8760a78e903218fef2a040fa42551d7273e
4
- data.tar.gz: 402f89f60de25ebe27a11c16e3e34fdbd3e8b854
2
+ SHA256:
3
+ metadata.gz: 553a980e772a1ce1d8990fc8d0744163b6615c5e9a4fe391d48ab73ac2219b2a
4
+ data.tar.gz: 7b922c56e568ac51cbb9cc3dbcb02c930984f94785ddd3b8ea76804ccff848de
5
5
  SHA512:
6
- metadata.gz: 1132dd0609803767926d6546549d5285a0197837dd512ea2980ce03b8be23c76e43016b3a63c36b4d43fd7bd8a7c055bc1085c482b659ea69fa2da1fa94f894e
7
- data.tar.gz: 59498ec443e22d08d01f8708a19dcf7b1b4b41a179e807fa0b6225d10f5642e2a3ab61bb04624c3ad80d9b0b2378d6c4b2b71651bb67bc0c25de5b22e0395120
6
+ metadata.gz: fc920c9d3f305e3e31f174ebbb5d8e7f935742a9b5bcd5a75b80646d5803746315e91e4937156a01f3fcc512c477b8770e6a665a86bd61a81120f0e305027652
7
+ data.tar.gz: 4dd48c11b6f59d2efc4aec15060d0c7db07541b1af4037dc8402b6ef701f43b88928aaaf3306e6ae0e1237a79f5fb360c992cf58648e26edb398f7adf843970e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,54 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ## flor 1.1.1 released 2021-03-03
6
+
7
+ * Use YAML to have more compact msg_to_detail_s
8
+
9
+
10
+ ## flor 1.1.0 released 2021-01-06
11
+
12
+ * Introduce Tasker #set_payload and #set_vars
13
+ * Introduce the ModuleGanger
14
+ * Allow for domain/dot.json taskers
15
+ * Introduce Flor::StagedBasicTasker
16
+ * Fix service/executor issue in Caller
17
+
18
+
19
+ ## flor 1.0.1 released 2020-11-23
20
+
21
+ * Accept sto_uri strings pointing to constant like 'DB'
22
+
23
+
24
+ ## flor 1.0.0 released 2020-11-22
25
+
26
+ * Lots of incremental improvements
27
+
28
+
29
+ ## flor 0.18.0 released 2019-05-05
30
+
31
+ * Refine BasicTasker#reply (more arg patterns)
32
+ * Fix "signal" vs exid: and payload:
33
+ * Make payload optional when cancelling
34
+ * Unlock `signal exid: other_execution_id "xxx"`
35
+ * Allow for `trap 'signal0' payload: { a: 'A' }`
36
+ * Allow for "on" in blocking mode (no block given)
37
+ * Turn "sequence" single string att results to tags
38
+ * gh-26, refine cancel / on_cancel and payload return
39
+ * Allow for custom :schema_info migration table
40
+ * Introduce a dedicated #refresh for all flor models
41
+ * Let scheduler sleep only 0.001s if @idle_count less than 1
42
+ * Implement Scheduler #dump and #load
43
+ * Default target #cancel and #kill to node '0'
44
+ * Expose taskname to tasker on detasking (@Subtletree)
45
+ * Refine BasicTasker#reply (more arg patterns)
46
+ * Allow for `trap 'signal0' payload: { a: 'A' }`
47
+ * Allow for "on" in blocking mode (no block given)
48
+ * Unlock `signal exid: other_execution_id "xxx"`
49
+ * Make payload optional when cancelling (default to payload as it was
50
+ upon reaching the cancelled node)
51
+
52
+
5
53
  ## flor 0.17.0 released 2019-04-08
6
54
 
7
55
  - Switch to 0.17.x
data/CREDITS.md CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  ## Contributors
5
5
 
6
+ * Olle Jonsson - https://github.com/olleolleolle
6
7
  * Ryan Scott - https://github.com/Subtletree
7
8
  * Jeffrey Hicks - https://github.com/jrhicks
8
9
  * David Verrier - https://github.com/dverrier
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2015-2019, John Mettraux, jmettraux+flor@gmail.com
2
+ Copyright (c) 2015-2021, 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
data/Makefile CHANGED
@@ -32,7 +32,7 @@ build: gemspec_validate
32
32
  mv $(NAME)-$(VERSION).gem pkg/
33
33
 
34
34
  push: build
35
- gem push pkg/$(NAME)-$(VERSION).gem
35
+ gem push --otp "$(OTP)" pkg/$(NAME)-$(VERSION).gem
36
36
 
37
37
 
38
38
  ## flor tasks ##
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  # flor
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/floraison/flor.svg)](http://travis-ci.org/floraison/flor)
4
+ [![tests](https://github.com/floraison/flor/workflows/test/badge.svg)](https://github.com/floraison/flor/actions)
5
5
  [![Gem Version](https://badge.fury.io/rb/flor.svg)](http://badge.fury.io/rb/flor)
6
6
 
7
7
  Flor is a "Ruby workflow engine", if that makes any sense.
@@ -11,6 +11,17 @@ Flor is a "Ruby workflow engine", if that makes any sense.
11
11
  * [twitter.com/@flor_workflow](https://twitter.com/flor_workflow)
12
12
 
13
13
 
14
+ ## use
15
+
16
+ As a workflow engine, flor takes as input process definitions and executes them. Those executions may in turn call pieces of Ruby code or external scripts that perform the actual work. Those pieces of code and scripts are called "taskers".
17
+
18
+ The classical way to use a language interpreter is to instantiate it as needed and let it die as the host execution ends. A workflow engine is more like a server, it may host multiple executions. And if the workflow engine stops, it may be restarted and pick the work back, when it was when it stopped.
19
+
20
+ Flor process definitions are written in the flor language, a programming language mostly inspired by Scheme and Ruby. As always with programming languages, readability is hoped for, for a workflow engine this is especially necessary since those business processes are the bread and butter of business users.
21
+
22
+ Using flor in your Ruby project requires you to clearly separate business process definitions from taskers. Since a flor instance may host multiple process executions based on one or more process definitions, many of the taskers may be reused from one definition to the other. For instance, if a "send-invoice-to-customer" tasker is created it might get used in the "process-retail-order" and the "process-big-distribution-order" processes.
23
+
24
+
14
25
  ## design
15
26
 
16
27
  * Strives to propose a scheming interpreter for long running executions
@@ -108,13 +119,34 @@ See [doc/](doc/).
108
119
 
109
120
  ## blog posts and presentations
110
121
 
111
- * [the flor language](http://jmettraux.skepti.ch/20180927.html?t=the_flor_language) - on the flor workflow definition language itself
122
+ * [flor workflow engine](http://jmettraux.skepti.ch/20190407.html?t=flor_workflow_engine&f=readme) - on flor itself
123
+ * [the flor language](http://jmettraux.skepti.ch/20180927.html?t=the_flor_language&f=readme) - on the flor workflow definition language itself
124
+ * [reddit answer on workflow engines](http://jmettraux.skepti.ch/20190416.html?t=reddit_answer_on_workflow_engines&f=readme) - an answer to a Reddit question on workflow engines, archived as a post
112
125
  * [Flor, hubristic interpreter](http://rubykaigi.org/2017/presentations/jmettraux.html) - RubyKaigi 2017, Hiroshima - presentation
113
126
  * [flor design 0](http://jmettraux.skepti.ch/20171021.html?t=flor_design_0&f=readme) - running a simple execution, what happens - blog post
114
127
  * [flor, branch to branch](https://speakerdeck.com/jmettraux/flor-branch-to-branch) - q1 2017 - very dry deck
115
128
  * [flor 2017](https://speakerdeck.com/jmettraux/flor-2017) - q1 2017 - very dry deck
116
129
 
117
130
 
131
+ ## other Ruby projects about workflows
132
+
133
+ There are various other Ruby and Ruby on Rails projects about workflows and business processes, each with its own take on them.
134
+
135
+ * [Dynflow](http://dynflow.github.io/) - "Dynflow (DYNamic workFLOW) is a workflow engine written in Ruby"
136
+ * [rails_workflow](https://github.com/madzhuga/rails_workflow) - "Rails Workflow Engine allows you to organize your application business logic by joining user- and auto- operations in processes"
137
+ * [rails_engine/flow_core](https://github.com/rails-engine/flow_core) - "A multi purpose, extendable, Workflow-net-based workflow engine for Rails applications"
138
+ * [Trailblazer](http://trailblazer.to/) - "The Advanced Business Logic Framework"
139
+ * [Petri Flow](https://github.com/hooopo/petri_flow) - "Petri Net Workflow Engine for Ruby" (Rails)
140
+ * [Pallets](https://github.com/linkyndy/pallets) - "Simple and reliable workflow engine, written in Ruby"
141
+ * [Gush](https://github.com/chaps-io/gush) - "Fast and distributed workflow runner using ActiveJob and Redis"
142
+
143
+ There is a [workflow engine](https://ruby.libhunt.com/categories/5786-workflow-engine) category on [Awesome Ruby](https://ruby.libhunt.com/).
144
+
145
+ If you want your engine/library to be added in this list, don't hesitate to ask me on [Gitter](https://gitter.im/floraison/flor) or via a pull request.
146
+
147
+ It's not limited to Ruby, but there is a wider list at [meirwah/awesome-workflow-engines](https://github.com/meirwah/awesome-workflow-engines).
148
+
149
+
118
150
  ## license
119
151
 
120
152
  MIT, see [LICENSE.txt](LICENSE.txt)
data/flor.gemspec CHANGED
@@ -10,8 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.authors = [ 'John Mettraux' ]
12
12
  s.email = [ 'jmettraux+flor@gmail.com' ]
13
- s.homepage = 'http://github.com/floraison'
14
- #s.rubyforge_project = 'flor'
13
+ s.homepage = 'https://github.com/floraison'
15
14
  s.license = 'MIT'
16
15
  s.summary = 'A Ruby workflow engine'
17
16
 
@@ -38,16 +37,16 @@ A Ruby workflow engine (ruote next generation)
38
37
  "#{s.name}.gemspec",
39
38
  ]
40
39
 
41
- s.add_runtime_dependency 'munemo', '~> 1.0', '>= 1.0.1'
42
- s.add_runtime_dependency 'raabro', '~> 1.1', '>= 1.1.5'
43
40
  #s.add_runtime_dependency 'rufus-lru', '~> 1.1'
44
- s.add_runtime_dependency 'fugit', '~> 1.1', '>= 1.1.8'
45
- s.add_runtime_dependency 'dense', '~> 1.1', '>= 1.1.6'
41
+ s.add_runtime_dependency 'munemo', '~> 1.0' # >= 1.0 and < 2
42
+ s.add_runtime_dependency 'raabro', '~> 1.1' # >= 1.1 and < 2
43
+ s.add_runtime_dependency 'fugit', '~> 1.2' # >= 1.2 and < 2
44
+ s.add_runtime_dependency 'dense', '~> 1.1' # >= 1.1 and < 2
46
45
 
47
- s.add_runtime_dependency 'sequel', '~> 5'
46
+ s.add_runtime_dependency 'sequel', '~> 5.0' # >= 5.0 and < 6
48
47
 
49
- s.add_development_dependency 'rspec', '~> 3.7'
50
- s.add_development_dependency 'terminal-table'
48
+ s.add_development_dependency 'rspec', '~> 3.8' # >= 3.8 and < 4
49
+ s.add_development_dependency 'terminal-table', '~> 1.8' # >= 1.8 and < 2
51
50
 
52
51
  s.require_path = 'lib'
53
52
  end
data/lib/flor.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require 'pp'
3
4
  require 'json'
5
+ require 'yaml'
4
6
  require 'logger'
5
7
  require 'thread'
6
8
  require 'digest'
@@ -14,8 +16,7 @@ require 'dense'
14
16
 
15
17
  module Flor
16
18
 
17
- VERSION = '0.17.0'
18
- #VERSION = '1.0.0'
19
+ VERSION = '1.1.1'
19
20
  end
20
21
 
21
22
  require 'flor/colours'
data/lib/flor/colours.rb CHANGED
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Flor
3
4
 
4
5
  COLS = Hash[*%w[
5
6
 
6
7
  reset 0;0
7
- bright 1 dim 2 underlined 4 blink 5 reverse 7 hidden 8 default 39
8
+ bright 1 dim 2 underlined 4 blink 5 reverse 7 hidden 8 strike 9 default 39
8
9
  black 30 red 31 green 32 yellow 33 blue 34 magenta 35 cyan 36
9
10
  light_gray 37 dark_gray 90 light_red 91 light_green 92
10
11
  light_yellow 93 light_blue 94 light_magenta 95 light_cyan 96 white 97
@@ -17,7 +18,8 @@ module Flor
17
18
  brown yellow purple magenta dark_grey dark_gray light_grey light_gray
18
19
 
19
20
  rd red bl blue bu blue ba black bk black gn green gr green dg dark_gray
20
- gy light_gray lg light_gray yl yellow y yellow ma magenta rs reset
21
+ gy light_gray lg light_gray yl yellow y yellow ma magenta wt white
22
+ rs reset
21
23
  br bright bri bright un underlined rv reverse bn blink blg bg_light_gray
22
24
  und underlined rev reverse
23
25
  ]]
@@ -28,7 +30,7 @@ module Flor
28
30
  if v.match(/\A\d/)
29
31
  class_eval(%{
30
32
  def #{k}(s=nil)
31
- s ? "[#{v}m" + s + "" : "[#{v}m"
33
+ s ? "[#{v}m" + s + "" : "[#{v}m"
32
34
  end })
33
35
  else
34
36
  class_eval(
data/lib/flor/conf.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Flor
3
4
 
data/lib/flor/core.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Flor
3
4
 
@@ -28,7 +29,7 @@ module Flor
28
29
 
29
30
  t =
30
31
  tree.is_a?(String) ?
31
- Flor.parse(tree, opts[:fname], opts) :
32
+ Flor.parse(tree, opts[:fname] || opts[:path], opts) :
32
33
  tree
33
34
 
34
35
  unless t
@@ -51,13 +52,13 @@ module Flor
51
52
  "given launch variables should come in a Hash, but it's a #{vs.class}"
52
53
  ) unless vs.is_a?(Hash)
53
54
 
54
- msg =
55
- { 'point' => 'execute',
56
- 'exid' => exid,
57
- 'nid' => '0',
58
- 'tree' => t,
59
- 'payload' => pl,
60
- 'vars' => vs }
55
+ msg = {
56
+ 'point' => 'execute',
57
+ 'exid' => exid,
58
+ 'nid' => '0',
59
+ 'tree' => t,
60
+ 'payload' => pl,
61
+ 'vars' => vs }
61
62
 
62
63
  msg['vdomain'] = opts[:vdomain] \
63
64
  if opts.has_key?(:vdomain)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Flor
3
4
 
@@ -211,7 +212,8 @@ module Flor
211
212
  #
212
213
  # tag: et al
213
214
 
214
- node['tree'] = message['tree'] = t = [ '_sqs', tree[0], tree[2] ]
215
+ node['tree'] = message['tree'] = t =
216
+ [ '_sqs', tree[0], tree[2] ]
215
217
 
216
218
  node['heat0'] = t[0]
217
219
  node['heat'] = h = n.deref(t[0])
@@ -221,14 +223,16 @@ module Flor
221
223
  #
222
224
  # rewrite `alpha` into `task alpha`
223
225
 
224
- l = message['tree'][2]
226
+ mt = message['tree']
227
+ l = mt[2]
225
228
 
226
- message['otree'] = Flor.dup(message['tree'])
229
+ message['otree'] = mt
227
230
 
228
- message['tree'][0] =
229
- 'task'
230
- message['tree'][1].unshift(
231
- [ '_att', [ [ '_sqs', heat[1]['tasker'], l ] ], l ])
231
+ node['tree'] = message['tree'] =
232
+ [ 'task', [
233
+ [ '_att', [ [ '_sqs', heat[1]['tasker'], l ] ], l ],
234
+ *mt[1]
235
+ ], l ]
232
236
  end
233
237
  end
234
238
 
@@ -287,9 +291,8 @@ end
287
291
 
288
292
  def receive(message)
289
293
 
290
- messages = leave_node(message)
291
-
292
294
  nid = message['nid']
295
+ messages = leave_node(message)
293
296
 
294
297
  return messages + toc_messages(message) unless nid
295
298
  # 'terminated' or 'ceased'
@@ -319,7 +322,9 @@ end
319
322
  cls = node['closures']
320
323
 
321
324
  pro = Flor::Procedure.make(self, node, message)
325
+
322
326
  pro.end
327
+ # do end the node
323
328
 
324
329
  cancels = pro.send(:wrap_cancel_children, 'cancel_trailing' => true)
325
330
 
@@ -380,12 +385,7 @@ end
380
385
 
381
386
  def error_reply(node, message, err)
382
387
 
383
- m = message
384
- .select { |k, v| %w[ sm exid nid from payload tree ].include?(k) }
385
-
386
- m['point'] = 'failed'
387
- m['fpoint'] = message['point']
388
- m['error'] = Flor.to_error(err)
388
+ m = Flor.to_error_message(message, err)
389
389
 
390
390
  @unit.logger.log_err(self, m, flag: true)
391
391
 
@@ -419,15 +419,14 @@ end
419
419
 
420
420
  last = (message['cause'] ||= [])[0]
421
421
 
422
- c = {
423
- 'cause' => cause,
424
- 'm' => message['m'],
425
- 'nid' => message['nid'],
426
- 'type' => message['type'],
427
- 'at' => last && last['at'] }
422
+ c = { 'cause' => cause, 'at' => last && last['at'] }
423
+ %w[ m sm nid type ].each { |k| c[k] = message[k] }
428
424
 
429
425
  return if c == last
430
426
 
427
+ # argh, the causes in the messages go most recent first
428
+ # while the statuses in the nodes go most recent last
429
+
431
430
  message['cause'] =
432
431
  [ c.tap { |h| h['at'] = Flor.tstamp } ] +
433
432
  message['cause']
@@ -448,7 +447,11 @@ end
448
447
  stack_cause(message) \
449
448
  if %w[ trigger cancel ].include?(message['point'])
450
449
 
451
- determine_heat(message)
450
+ begin
451
+ determine_heat(message)
452
+ rescue => e
453
+ raise e unless message['point'] == 'failed'
454
+ end
452
455
 
453
456
  ms = []
454
457
  ms += @unit.notify(self, message) # pre
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  class Flor::Node
3
4
 
@@ -156,19 +157,6 @@ class Flor::Node
156
157
  nil
157
158
  end
158
159
 
159
- #def lookup_tree(nid)
160
- # climb_down_for_tree(nid) ||
161
- # climb_up_for_tree(nid) ||
162
- #end
163
- #def climb_up_for_tree(nid)
164
- # # ...
165
- #end
166
- #def climb_down_for_tree(nid)
167
- # # ...
168
- #end
169
- #
170
- # that might be the way...
171
-
172
160
  def lookup_value(path)
173
161
 
174
162
  original_path = path
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  class Flor::Procedure < Flor::Node
3
4
 
@@ -386,18 +387,30 @@ class Flor::Procedure < Flor::Node
386
387
  end
387
388
  end
388
389
 
390
+ # From the incoming message, return the most recent cause for this node
391
+ #
389
392
  def message_cause
390
393
 
391
394
  (@message['cause'] || [])
392
395
  .find { |c| c['nid'] == nid }
393
396
  end
394
397
 
398
+ # Given the current node status and the incoming message, returns the
399
+ # upstream cause that lead to the status.
400
+ # Returns nil if the incoming message is not related to the current status.
401
+ #
402
+ def status_cause
403
+
404
+ m = node_status['m']
405
+
406
+ (@message['cause'] || []).find { |c| c['m'] == m }
407
+ end
408
+
395
409
  def pop_on_receive_last
396
410
 
397
411
  orl = @node['on_receive_last']
398
412
 
399
- return nil unless orl
400
- return nil if orl.empty?
413
+ return nil if orl.nil? || orl.empty?
401
414
 
402
415
  c = message_cause
403
416
 
@@ -411,15 +424,16 @@ class Flor::Procedure < Flor::Node
411
424
 
412
425
  @node['mtime'] = Flor.tstamp
413
426
 
414
- orl.each do |m|
415
-
416
- m['from'] = @node['parent'] if m['from'] == 'parent'
427
+ orl
428
+ .each do |m|
417
429
 
418
- #m['payload'] ||= Flor.dup(@node['payload'])
419
- # No, let re_applier supply payload
420
- end
430
+ m['from'] = @node['parent'] \
431
+ if m['from'] == 'parent'
421
432
 
422
- orl
433
+ m['payload'] =
434
+ m.delete('force_payload') ||
435
+ message['payload']
436
+ end
423
437
  end
424
438
 
425
439
  def receive_from_child_when_closed
@@ -447,8 +461,21 @@ class Flor::Procedure < Flor::Node
447
461
 
448
462
  @fcid &&
449
463
  Flor.same_branch?(nid, from) &&
450
- (c = children[@fcid]) &&
451
- c[0] == '_att'
464
+ (c = children[@fcid]) && c[0] == '_att'
465
+ end
466
+
467
+ def from_keyed_att?
468
+
469
+ @fcid &&
470
+ Flor.same_branch?(nid, from) &&
471
+ (c = children[@fcid]) && c[0] == '_att' && c[1].size == 2
472
+ end
473
+
474
+ def from_unkeyed_att?
475
+
476
+ @fcid &&
477
+ Flor.same_branch?(nid, from) &&
478
+ (c = children[@fcid]) && c[0] == '_att' && c[1].size == 1
452
479
  end
453
480
 
454
481
  def from_sub_nid
@@ -804,8 +831,16 @@ class Flor::Procedure < Flor::Node
804
831
  def wrap_cancel_nodes(nids, h)
805
832
 
806
833
  (nids || [])
807
- .collect { |i| wrap_cancel(h.merge('nid' => i, 'from' => nid)) }
834
+ .collect { |i|
835
+ n = @execution['nodes'][i]
836
+ s = n && n['status'].last
837
+ if n == nil || (s['status'] == 'closed' && s['point'] == 'cancel')
838
+ nil
839
+ else
840
+ wrap_cancel(h.merge('nid' => i, 'from' => nid))
841
+ end }
808
842
  .flatten(1)
843
+ .compact
809
844
  end
810
845
 
811
846
  def wrap_cancelled
@@ -828,6 +863,16 @@ class Flor::Procedure < Flor::Node
828
863
  #
829
864
  def do_cancel
830
865
 
866
+ @message['payload'] ||= Flor.dup(@node['payload'])
867
+ #
868
+ # Ensure the 'cancel' message has a payload.
869
+ # If not, let's use the payload as it was upon reaching this node.
870
+
871
+ return wrap if node_closed? && status_cause
872
+ #
873
+ # if the node is cancelled and that is caused by a message upstream
874
+ # that caused the incoming message, simply reply immediately...
875
+
831
876
  if orl = @message['on_receive_last']
832
877
  #
833
878
  # the message on_receive_last is used by the re_apply feature