flor 0.17.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +48 -0
- data/CREDITS.md +1 -0
- data/LICENSE.txt +1 -1
- data/Makefile +1 -1
- data/README.md +34 -2
- data/flor.gemspec +8 -9
- data/lib/flor.rb +3 -2
- data/lib/flor/colours.rb +5 -3
- data/lib/flor/conf.rb +1 -0
- data/lib/flor/core.rb +9 -8
- data/lib/flor/core/executor.rb +25 -22
- data/lib/flor/core/node.rb +1 -13
- data/lib/flor/core/procedure.rb +57 -12
- data/lib/flor/core/texecutor.rb +35 -3
- data/lib/flor/djan.rb +1 -0
- data/lib/flor/errors.rb +1 -0
- data/lib/flor/flor.rb +173 -29
- data/lib/flor/id.rb +5 -1
- data/lib/flor/log.rb +20 -8
- data/lib/flor/migrations/0001_tables.rb +1 -0
- data/lib/flor/migrations/0002_cunit_and_munit.rb +1 -0
- data/lib/flor/migrations/0003_timer_onid_bnid.rb +1 -0
- data/lib/flor/migrations/0004_trap_bnid.rb +1 -0
- data/lib/flor/migrations/0005_pointer_content.rb +1 -0
- data/lib/flor/parser.rb +19 -11
- data/lib/flor/pcore/_apply.rb +1 -0
- data/lib/flor/pcore/_arr.rb +1 -0
- data/lib/flor/pcore/_atom.rb +1 -0
- data/lib/flor/pcore/_att.rb +1 -0
- data/lib/flor/pcore/_coll.rb +1 -0
- data/lib/flor/pcore/_dmute.rb +5 -1
- data/lib/flor/pcore/_dol.rb +1 -0
- data/lib/flor/pcore/_dqs.rb +1 -0
- data/lib/flor/pcore/_dump.rb +1 -0
- data/lib/flor/pcore/_err.rb +1 -0
- data/lib/flor/pcore/_head.rb +1 -0
- data/lib/flor/pcore/_obj.rb +1 -0
- data/lib/flor/pcore/_pat_.rb +1 -0
- data/lib/flor/pcore/_pat_arr.rb +1 -0
- data/lib/flor/pcore/_pat_guard.rb +1 -0
- data/lib/flor/pcore/_pat_obj.rb +1 -0
- data/lib/flor/pcore/_pat_or.rb +1 -0
- data/lib/flor/pcore/_pat_regex.rb +1 -0
- data/lib/flor/pcore/_ref.rb +1 -0
- data/lib/flor/pcore/_rxs.rb +1 -0
- data/lib/flor/pcore/_skip.rb +1 -0
- data/lib/flor/pcore/_val.rb +1 -0
- data/lib/flor/pcore/all.rb +1 -0
- data/lib/flor/pcore/andor.rb +1 -0
- data/lib/flor/pcore/any.rb +1 -0
- data/lib/flor/pcore/apply.rb +1 -0
- data/lib/flor/pcore/arith.rb +1 -0
- data/lib/flor/pcore/array_qmark.rb +1 -0
- data/lib/flor/pcore/break.rb +13 -1
- data/lib/flor/pcore/case.rb +1 -0
- data/lib/flor/pcore/cmp.rb +1 -0
- data/lib/flor/pcore/collect.rb +2 -1
- data/lib/flor/pcore/cond.rb +1 -0
- data/lib/flor/pcore/cursor.rb +45 -3
- data/lib/flor/pcore/define.rb +1 -0
- data/lib/flor/pcore/detect.rb +1 -0
- data/lib/flor/pcore/do_return.rb +1 -0
- data/lib/flor/pcore/each.rb +1 -0
- data/lib/flor/pcore/echo.rb +1 -0
- data/lib/flor/pcore/empty.rb +1 -0
- data/lib/flor/pcore/fail.rb +1 -0
- data/lib/flor/pcore/filter.rb +1 -0
- data/lib/flor/pcore/find.rb +1 -0
- data/lib/flor/pcore/flatten.rb +1 -0
- data/lib/flor/pcore/for_each.rb +1 -0
- data/lib/flor/pcore/if.rb +1 -0
- data/lib/flor/pcore/includes.rb +1 -0
- data/lib/flor/pcore/inject.rb +1 -0
- data/lib/flor/pcore/iterator.rb +1 -0
- data/lib/flor/pcore/keys.rb +1 -0
- data/lib/flor/pcore/length.rb +1 -0
- data/lib/flor/pcore/loop.rb +1 -0
- data/lib/flor/pcore/map.rb +1 -0
- data/lib/flor/pcore/match.rb +1 -0
- data/lib/flor/pcore/matchr.rb +1 -0
- data/lib/flor/pcore/max.rb +1 -0
- data/lib/flor/pcore/merge.rb +1 -0
- data/lib/flor/pcore/move.rb +1 -0
- data/lib/flor/pcore/noeval.rb +1 -0
- data/lib/flor/pcore/noret.rb +1 -0
- data/lib/flor/pcore/not.rb +1 -0
- data/lib/flor/pcore/on.rb +34 -9
- data/lib/flor/pcore/on_cancel.rb +1 -0
- data/lib/flor/pcore/on_error.rb +1 -0
- data/lib/flor/pcore/push.rb +1 -0
- data/lib/flor/pcore/rand.rb +1 -0
- data/lib/flor/pcore/range.rb +1 -0
- data/lib/flor/pcore/reduce.rb +1 -0
- data/lib/flor/pcore/return.rb +1 -0
- data/lib/flor/pcore/reverse.rb +1 -0
- data/lib/flor/pcore/select.rb +1 -0
- data/lib/flor/pcore/sequence.rb +49 -0
- data/lib/flor/pcore/set.rb +1 -0
- data/lib/flor/pcore/shuffle.rb +1 -0
- data/lib/flor/pcore/slice.rb +1 -0
- data/lib/flor/pcore/sort.rb +1 -0
- data/lib/flor/pcore/sort_by.rb +1 -0
- data/lib/flor/pcore/split.rb +1 -0
- data/lib/flor/pcore/stall.rb +1 -0
- data/lib/flor/pcore/strings.rb +1 -0
- data/lib/flor/pcore/timestamp.rb +1 -0
- data/lib/flor/pcore/to_array.rb +1 -0
- data/lib/flor/pcore/twig.rb +1 -0
- data/lib/flor/pcore/type_of.rb +1 -0
- data/lib/flor/pcore/until.rb +1 -0
- data/lib/flor/punit/abort.rb +50 -0
- data/lib/flor/punit/c_collect.rb +1 -0
- data/lib/flor/punit/c_each.rb +19 -0
- data/lib/flor/punit/c_for_each.rb +2 -1
- data/lib/flor/punit/c_iterator.rb +2 -1
- data/lib/flor/punit/c_map.rb +1 -0
- data/lib/flor/punit/cancel.rb +10 -1
- data/lib/flor/punit/concurrence.rb +7 -5
- data/lib/flor/punit/cron.rb +1 -0
- data/lib/flor/punit/do_trap.rb +1 -0
- data/lib/flor/punit/every.rb +1 -0
- data/lib/flor/punit/graft.rb +1 -0
- data/lib/flor/punit/{m_ram.rb → m_receive_and_merge.rb} +5 -4
- data/lib/flor/punit/on_timeout.rb +1 -0
- data/lib/flor/punit/part.rb +1 -0
- data/lib/flor/punit/schedule.rb +1 -0
- data/lib/flor/punit/signal.rb +30 -5
- data/lib/flor/punit/sleep.rb +1 -0
- data/lib/flor/punit/task.rb +9 -2
- data/lib/flor/punit/trace.rb +1 -0
- data/lib/flor/punit/trap.rb +41 -1
- data/lib/flor/to_string.rb +1 -0
- data/lib/flor/tools/env.rb +1 -0
- data/lib/flor/tools/firb.rb +33 -0
- data/lib/flor/tools/shell.rb +13 -3
- data/lib/flor/tools/shell_out.rb +1 -0
- data/lib/flor/tt.rb +98 -0
- data/lib/flor/unit.rb +3 -0
- data/lib/flor/unit/caller.rb +158 -23
- data/lib/flor/unit/caller_jruby.rb +133 -0
- data/lib/flor/unit/dump.rb +36 -0
- data/lib/flor/unit/executor.rb +28 -18
- data/lib/flor/unit/ganger.rb +30 -18
- data/lib/flor/unit/gangers.rb +125 -0
- data/lib/flor/unit/hloader.rb +34 -7
- data/lib/flor/unit/hook.rb +3 -0
- data/lib/flor/unit/hooker.rb +32 -15
- data/lib/flor/unit/journal.rb +23 -0
- data/lib/flor/unit/loader.rb +142 -15
- data/lib/flor/unit/logger.rb +35 -7
- data/lib/flor/unit/models.rb +48 -10
- data/lib/flor/unit/models/execution.rb +51 -0
- data/lib/flor/unit/models/message.rb +6 -0
- data/lib/flor/unit/models/pointer.rb +1 -0
- data/lib/flor/unit/models/timer.rb +1 -0
- data/lib/flor/unit/models/trace.rb +1 -0
- data/lib/flor/unit/models/trap.rb +15 -6
- data/lib/flor/unit/scheduler.rb +211 -61
- data/lib/flor/unit/spooler.rb +1 -0
- data/lib/flor/unit/storage.rb +117 -73
- data/lib/flor/unit/taskers.rb +115 -1
- data/lib/flor/unit/waiter.rb +22 -17
- data/lib/flor/unit/wlist.rb +19 -8
- metadata +26 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 553a980e772a1ce1d8990fc8d0744163b6615c5e9a4fe391d48ab73ac2219b2a
|
4
|
+
data.tar.gz: 7b922c56e568ac51cbb9cc3dbcb02c930984f94785ddd3b8ea76804ccff848de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2015-
|
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
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
# flor
|
3
3
|
|
4
|
-
[![
|
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
|
-
* [
|
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 = '
|
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 '
|
45
|
-
s.add_runtime_dependency '
|
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.
|
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 = '
|
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
|
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 + "[0;
|
33
|
+
s ? "[#{v}m" + s + "[0;0m" : "[#{v}m"
|
32
34
|
end })
|
33
35
|
else
|
34
36
|
class_eval(
|
data/lib/flor/conf.rb
CHANGED
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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)
|
data/lib/flor/core/executor.rb
CHANGED
@@ -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 =
|
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
|
-
|
226
|
+
mt = message['tree']
|
227
|
+
l = mt[2]
|
225
228
|
|
226
|
-
message['otree'] =
|
229
|
+
message['otree'] = mt
|
227
230
|
|
228
|
-
|
229
|
-
'task'
|
230
|
-
|
231
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/flor/core/node.rb
CHANGED
@@ -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
|
data/lib/flor/core/procedure.rb
CHANGED
@@ -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
|
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
|
415
|
-
|
416
|
-
m['from'] = @node['parent'] if m['from'] == 'parent'
|
427
|
+
orl
|
428
|
+
.each do |m|
|
417
429
|
|
418
|
-
|
419
|
-
|
420
|
-
end
|
430
|
+
m['from'] = @node['parent'] \
|
431
|
+
if m['from'] == 'parent'
|
421
432
|
|
422
|
-
|
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
|
-
|
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|
|
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
|