flor 0.18.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +29 -0
- data/CREDITS.md +1 -0
- data/LICENSE.txt +1 -1
- data/Makefile +1 -1
- data/README.md +16 -2
- data/flor.gemspec +1 -2
- 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 +20 -16
- data/lib/flor/core/node.rb +1 -13
- data/lib/flor/core/procedure.rb +10 -1
- 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 +172 -26
- data/lib/flor/id.rb +5 -1
- data/lib/flor/log.rb +14 -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 +1 -0
- 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 +1 -0
- 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 +4 -3
- 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 +1 -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 +1 -0
- 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 +1 -0
- data/lib/flor/punit/sleep.rb +1 -0
- data/lib/flor/punit/task.rb +1 -0
- data/lib/flor/punit/trace.rb +1 -0
- data/lib/flor/punit/trap.rb +10 -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 +19 -13
- data/lib/flor/unit/ganger.rb +9 -12
- 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 +8 -1
- 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 +21 -1
- 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 +3 -2
- data/lib/flor/unit/scheduler.rb +51 -36
- data/lib/flor/unit/spooler.rb +1 -0
- data/lib/flor/unit/storage.rb +113 -84
- data/lib/flor/unit/taskers.rb +70 -1
- data/lib/flor/unit/waiter.rb +22 -17
- data/lib/flor/unit/wlist.rb +19 -8
- metadata +16 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8cb81ff9507389113f022e056168866a3ccccb9b7fb7cd695c7cf62224ed3043
|
4
|
+
data.tar.gz: d6cf730b9b0dbe18951c43fc54d0fa94ea2fba545fe25a812c11a9b9b06145f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 686d2447419ee1e58e97d23b8dc627afedaabe26196d3849d365cfef2d42a9b3027d91c6bfff98c5dedd3423b56b2add907c2831c24ede4d16fffec9f7c2ed24
|
7
|
+
data.tar.gz: 7a31f1c24e6b8d2df514c63b2f60472320fb2f2a42ce9a62ceb0b4c7e89a3b6dd66b1032eb0c7e3b26c9497c2474262c5cfa1f91d2bb6f7a3062e5f76c996bbc
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,35 @@
|
|
2
2
|
# CHANGELOG.md
|
3
3
|
|
4
4
|
|
5
|
+
## flor 1.2.0 released 2021-03-15
|
6
|
+
|
7
|
+
* Add #attd, #attl, #att_texts to Flor::Pointer
|
8
|
+
|
9
|
+
|
10
|
+
## flor 1.1.1 released 2021-03-03
|
11
|
+
|
12
|
+
* Use YAML to have more compact msg_to_detail_s
|
13
|
+
|
14
|
+
|
15
|
+
## flor 1.1.0 released 2021-01-06
|
16
|
+
|
17
|
+
* Introduce Tasker #set_payload and #set_vars
|
18
|
+
* Introduce the ModuleGanger
|
19
|
+
* Allow for domain/dot.json taskers
|
20
|
+
* Introduce Flor::StagedBasicTasker
|
21
|
+
* Fix service/executor issue in Caller
|
22
|
+
|
23
|
+
|
24
|
+
## flor 1.0.1 released 2020-11-23
|
25
|
+
|
26
|
+
* Accept sto_uri strings pointing to constant like 'DB'
|
27
|
+
|
28
|
+
|
29
|
+
## flor 1.0.0 released 2020-11-22
|
30
|
+
|
31
|
+
* Lots of incremental improvements
|
32
|
+
|
33
|
+
|
5
34
|
## flor 0.18.0 released 2019-05-05
|
6
35
|
|
7
36
|
* Refine BasicTasker#reply (more arg patterns)
|
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
|
@@ -123,8 +134,11 @@ There are various other Ruby and Ruby on Rails projects about workflows and busi
|
|
123
134
|
|
124
135
|
* [Dynflow](http://dynflow.github.io/) - "Dynflow (DYNamic workFLOW) is a workflow engine written in Ruby"
|
125
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"
|
126
|
-
* [rails_engine/
|
137
|
+
* [rails_engine/flow_core](https://github.com/rails-engine/flow_core) - "A multi purpose, extendable, Workflow-net-based workflow engine for Rails applications"
|
127
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"
|
128
142
|
|
129
143
|
There is a [workflow engine](https://ruby.libhunt.com/categories/5786-workflow-engine) category on [Awesome Ruby](https://ruby.libhunt.com/).
|
130
144
|
|
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
|
|
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.2.0'
|
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
|
|
@@ -447,7 +447,11 @@ end
|
|
447
447
|
stack_cause(message) \
|
448
448
|
if %w[ trigger cancel ].include?(message['point'])
|
449
449
|
|
450
|
-
|
450
|
+
begin
|
451
|
+
determine_heat(message)
|
452
|
+
rescue => e
|
453
|
+
raise e unless message['point'] == 'failed'
|
454
|
+
end
|
451
455
|
|
452
456
|
ms = []
|
453
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
|
|
@@ -830,8 +831,16 @@ class Flor::Procedure < Flor::Node
|
|
830
831
|
def wrap_cancel_nodes(nids, h)
|
831
832
|
|
832
833
|
(nids || [])
|
833
|
-
.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 }
|
834
842
|
.flatten(1)
|
843
|
+
.compact
|
835
844
|
end
|
836
845
|
|
837
846
|
def wrap_cancelled
|
data/lib/flor/core/texecutor.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module Flor
|
3
4
|
|
@@ -235,7 +236,7 @@ module Flor
|
|
235
236
|
|
236
237
|
c = ! (ENV['FLOR_DEBUG'] || '').match(/conf/)
|
237
238
|
e = self.new('conf' => c)
|
238
|
-
r = e.launch(source, payload: fs, vars: vs)
|
239
|
+
r = e.launch(source, payload: fs, vars: vs, path: path)
|
239
240
|
|
240
241
|
unless r['point'] == 'terminated'
|
241
242
|
ae = ArgumentError.new(
|
@@ -250,14 +251,20 @@ module Flor
|
|
250
251
|
o['_path'] = path
|
251
252
|
o['root'] ||= Flor.relativize_path(vs['root'])
|
252
253
|
elsif o.is_a?(Array)
|
253
|
-
o.each { |ee| ee['_path'] = path }
|
254
|
+
o.each { |ee| ee['_path'] = path if ee.is_a?(Hash) }
|
254
255
|
end
|
255
256
|
|
256
|
-
o
|
257
|
+
rework_conf(o)
|
257
258
|
end
|
258
259
|
|
259
260
|
def interpret_path(path, context=nil)
|
260
261
|
|
262
|
+
path = File.join(path, 'etc/conf.json') if File.directory?(path)
|
263
|
+
|
264
|
+
fail ArgumentError.new(
|
265
|
+
"flor configuration file not found #{path.inspect}"
|
266
|
+
) unless File.exist?(path)
|
267
|
+
|
261
268
|
interpret(path, load(path), context || {})
|
262
269
|
end
|
263
270
|
|
@@ -292,6 +299,31 @@ module Flor
|
|
292
299
|
|
293
300
|
ps.last == 'etc' ? File.absolute_path(File.join(dir, '..')) : dir
|
294
301
|
end
|
302
|
+
|
303
|
+
protected
|
304
|
+
|
305
|
+
# For now, only the return procedure has to be marshalled back
|
306
|
+
# to the "return" string, gh-36
|
307
|
+
#
|
308
|
+
def rework_conf(o)
|
309
|
+
|
310
|
+
case o
|
311
|
+
when Array
|
312
|
+
o.collect { |e|
|
313
|
+
rework_conf(e) }
|
314
|
+
when Hash
|
315
|
+
o.inject({}) { |h, (k, v)|
|
316
|
+
h[k] =
|
317
|
+
if Flor.is_proc_tree?(v) && v[1]['proc'] == 'return'
|
318
|
+
'return'
|
319
|
+
else
|
320
|
+
rework_conf(v)
|
321
|
+
end
|
322
|
+
h }
|
323
|
+
else
|
324
|
+
o
|
325
|
+
end
|
326
|
+
end
|
295
327
|
end
|
296
328
|
end
|
297
329
|
end
|
data/lib/flor/djan.rb
CHANGED
data/lib/flor/errors.rb
CHANGED
data/lib/flor/flor.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module Flor
|
3
4
|
|
4
5
|
NAME_REX = '[a-zA-Z0-9_]+'
|
5
|
-
UNIT_NAME_REX = /\A#{NAME_REX}\z
|
6
|
-
DOMAIN_NAME_REX = /\A#{NAME_REX}(\.#{NAME_REX})*\z
|
7
|
-
FLOW_NAME_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)\.([a-zA-Z0-9_-]+)\z
|
6
|
+
UNIT_NAME_REX = /\A#{NAME_REX}\z/.freeze
|
7
|
+
DOMAIN_NAME_REX = /\A#{NAME_REX}(\.#{NAME_REX})*\z/.freeze
|
8
|
+
FLOW_NAME_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)\.([a-zA-Z0-9_-]+)\z/.freeze
|
8
9
|
|
9
|
-
|
10
|
-
DOMAIN_UNIT_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)-(#{NAME_REX})[-$]/
|
10
|
+
DOMAIN_UNIT_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)-(#{NAME_REX})[-$]/.freeze
|
11
11
|
|
12
12
|
SPLAT_REGEX = /\A(.*)__(_|\d+)\z/.freeze
|
13
13
|
|
@@ -20,7 +20,7 @@ module Flor
|
|
20
20
|
signal cancel
|
21
21
|
terminated failed ceased
|
22
22
|
idle
|
23
|
-
|
23
|
+
].freeze
|
24
24
|
|
25
25
|
class << self
|
26
26
|
|
@@ -77,6 +77,23 @@ module Flor
|
|
77
77
|
deep_merge(o0, o1, true)
|
78
78
|
end
|
79
79
|
|
80
|
+
def dup_message(m)
|
81
|
+
|
82
|
+
tc = m.delete('tconf')
|
83
|
+
m1 = Flor.dup(m)
|
84
|
+
m1['tconf'] = tc
|
85
|
+
.inject({}) { |h, (k, v)|
|
86
|
+
h[k] =
|
87
|
+
case k
|
88
|
+
when 'class' then v
|
89
|
+
else Flor.dup(v)
|
90
|
+
end
|
91
|
+
h
|
92
|
+
} if tc
|
93
|
+
|
94
|
+
m1
|
95
|
+
end
|
96
|
+
|
80
97
|
def false?(o)
|
81
98
|
|
82
99
|
o == nil || o == false
|
@@ -87,6 +104,20 @@ module Flor
|
|
87
104
|
o != nil && o != false
|
88
105
|
end
|
89
106
|
|
107
|
+
def yes?(o)
|
108
|
+
|
109
|
+
oo = o.respond_to?(:downcase) ? o.downcase : o
|
110
|
+
|
111
|
+
[ 'y', 'yes', 'true', true ].include?(o)
|
112
|
+
end
|
113
|
+
|
114
|
+
def no?(o)
|
115
|
+
|
116
|
+
oo = o.respond_to?(:downcase) ? o.downcase : o
|
117
|
+
|
118
|
+
[ 'n', 'no', 'false', false ].include?(o)
|
119
|
+
end
|
120
|
+
|
90
121
|
def to_error(o)
|
91
122
|
|
92
123
|
h = {}
|
@@ -109,19 +140,24 @@ module Flor
|
|
109
140
|
h['cwd'] = Dir.pwd
|
110
141
|
h['rlp'] = $: if o.is_a?(::LoadError)
|
111
142
|
|
143
|
+
h['details'] = o.details if o.respond_to?(:details)
|
144
|
+
h['details'] = o.flor_details if o.respond_to?(:flor_details)
|
145
|
+
|
112
146
|
h
|
113
147
|
end
|
114
148
|
|
115
|
-
|
149
|
+
TO_ERROR_MESSAGE_KEYS = %w[ sm exid nid from payload tree er tasker ]
|
150
|
+
|
151
|
+
def to_error_message(message, error)
|
116
152
|
|
117
|
-
|
118
|
-
|
119
|
-
|
153
|
+
#puts "---"
|
154
|
+
#puts caller
|
155
|
+
m = message.select { |k, v| TO_ERROR_MESSAGE_KEYS.include?(k) }
|
120
156
|
|
121
157
|
m['point'] = 'failed'
|
122
158
|
m['fpoint'] = message['point']
|
123
159
|
m['fm'] = message['m']
|
124
|
-
m['error'] = to_error(
|
160
|
+
m['error'] = to_error(error)
|
125
161
|
|
126
162
|
m
|
127
163
|
end
|
@@ -243,13 +279,19 @@ module Flor
|
|
243
279
|
#
|
244
280
|
# functions about time
|
245
281
|
|
282
|
+
# Used by the storage in its next_time endeavours
|
283
|
+
#
|
284
|
+
def tstam
|
285
|
+
Time.now.utc.strftime('%FT%T')
|
286
|
+
end
|
287
|
+
|
246
288
|
def isostamp(show_date, show_time, show_usec, time)
|
247
289
|
|
248
290
|
t = (time || Time.now).utc
|
249
291
|
s = StringIO.new
|
250
292
|
|
251
|
-
s << t.strftime('%
|
252
|
-
s << t.strftime('T%
|
293
|
+
s << t.strftime('%F') if show_date # YYYY-mm-dd
|
294
|
+
s << t.strftime('T%T') if show_time # THH:MM:SS
|
253
295
|
s << sprintf('.%06d', t.usec) if show_time && show_usec
|
254
296
|
s << 'Z' if show_time
|
255
297
|
|
@@ -287,6 +329,11 @@ module Flor
|
|
287
329
|
isostamp(false, true, true, t)
|
288
330
|
end
|
289
331
|
|
332
|
+
def monow
|
333
|
+
|
334
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
335
|
+
end
|
336
|
+
|
290
337
|
# def to_time(ts)
|
291
338
|
#
|
292
339
|
# m = ts.match(/\A(\d{4})(\d{2})(\d{2})\.(\d{2})(\d{2})(\d{2})(\d+)([uU]?)\z/)
|
@@ -331,12 +378,20 @@ module Flor
|
|
331
378
|
sub_domain?(dom, sub)
|
332
379
|
end
|
333
380
|
|
381
|
+
def dot_join(*elts)
|
382
|
+
|
383
|
+
elts.collect(&:to_s).select { |e| e.length > 0 }.join('.')
|
384
|
+
end
|
385
|
+
|
334
386
|
def sub_domain?(dom, sub)
|
335
387
|
|
336
|
-
dom
|
337
|
-
|
338
|
-
|
388
|
+
d = dom.is_a?(Array) ? dot_join(*dom) : dom.to_s
|
389
|
+
|
390
|
+
d == '' ||
|
391
|
+
sub == d ||
|
392
|
+
sub[0, d.length + 1] == d + '.'
|
339
393
|
end
|
394
|
+
alias subdomain? sub_domain?
|
340
395
|
|
341
396
|
def split_domain_unit(s)
|
342
397
|
|
@@ -385,6 +440,31 @@ module Flor
|
|
385
440
|
(s ? (t[1] == s) : t[1].is_a?(String))
|
386
441
|
end
|
387
442
|
|
443
|
+
def is_leaf_tree?(t)
|
444
|
+
|
445
|
+
t.is_a?(Array) &&
|
446
|
+
t[2].is_a?(Integer) &&
|
447
|
+
Flor::Pro::Atom.names.include?(t[0])
|
448
|
+
end
|
449
|
+
#alias is_atom_tree? is_leaf_tree?
|
450
|
+
|
451
|
+
# # Array, object or atom tree
|
452
|
+
# #
|
453
|
+
# def is_value_tree?(o)
|
454
|
+
#
|
455
|
+
# o.is_a?(Array) &&
|
456
|
+
# %w[ _num _boo _sqs _dqs _rxs _nul _arr _obj ].include?(o[0]) &&
|
457
|
+
# o[2].is_a?(Integer)
|
458
|
+
# end
|
459
|
+
|
460
|
+
def is_collection_tree?(t)
|
461
|
+
|
462
|
+
t.is_a?(Array) &&
|
463
|
+
(t[0] == '_arr' || t[0] == '_obj') &&
|
464
|
+
t[1].is_a?(Array)
|
465
|
+
end
|
466
|
+
alias is_coll_tree? is_collection_tree?
|
467
|
+
|
388
468
|
def is_att_tree?(t)
|
389
469
|
|
390
470
|
t.is_a?(Array) &&
|
@@ -418,15 +498,6 @@ module Flor
|
|
418
498
|
t.is_a?(Array) && t[0].is_a?(String) && t[0] != '_' && t[1] == []
|
419
499
|
end
|
420
500
|
|
421
|
-
# # Array, object or atom tree
|
422
|
-
# #
|
423
|
-
# def is_value_tree?(o)
|
424
|
-
#
|
425
|
-
# o.is_a?(Array) &&
|
426
|
-
# %w[ _num _boo _sqs _dqs _rxs _nul _arr _obj ].include?(o[0]) &&
|
427
|
-
# o[2].is_a?(Integer)
|
428
|
-
# end
|
429
|
-
|
430
501
|
def is_proc_tree?(o)
|
431
502
|
|
432
503
|
o.is_a?(Array) &&
|
@@ -483,7 +554,7 @@ module Flor
|
|
483
554
|
def is_ref_tree?(o)
|
484
555
|
|
485
556
|
o.is_a?(Array) &&
|
486
|
-
(o[0]
|
557
|
+
Flor::Pro::Ref.names.include?(o[0]) &&
|
487
558
|
o[2].is_a?(Integer) &&
|
488
559
|
o[1].is_a?(Array) &&
|
489
560
|
o[1].all? { |e| is_sqs_tree?(e) || is_num_tree?(e) }
|
@@ -520,6 +591,81 @@ module Flor
|
|
520
591
|
end
|
521
592
|
|
522
593
|
|
594
|
+
#
|
595
|
+
# tree to flor code
|
596
|
+
|
597
|
+
# Given a tree returns the equivalent flor piece of code
|
598
|
+
#
|
599
|
+
def tree_to_flor(t, opts={})
|
600
|
+
|
601
|
+
o = opts[:o] ||= StringIO.new
|
602
|
+
opts[:ind] ||= ''
|
603
|
+
|
604
|
+
t_to_flor(t, opts)
|
605
|
+
|
606
|
+
o.string
|
607
|
+
end
|
608
|
+
|
609
|
+
protected
|
610
|
+
|
611
|
+
def t_to_flor(t, opts)
|
612
|
+
|
613
|
+
o = opts[:o]
|
614
|
+
i = opts[:ind]
|
615
|
+
|
616
|
+
t1 = t[1]
|
617
|
+
|
618
|
+
return o << '_' if t[0, 2] == [ '_', [] ]
|
619
|
+
return c_to_flor(t, opts) if is_coll_tree?(t)
|
620
|
+
return o << JSON.dump(t1) if is_leaf_tree?(t)
|
621
|
+
return o << t1.collect { |a| a[1].to_s }.join('.') if is_ref_tree?(t)
|
622
|
+
|
623
|
+
o << i << t[0]
|
624
|
+
|
625
|
+
if t1.is_a?(Array)
|
626
|
+
|
627
|
+
atts, ctrees = t1.partition { |ct| is_att_tree?(ct) }
|
628
|
+
|
629
|
+
atts.each do |at|
|
630
|
+
ats = at[1]
|
631
|
+
o << ' '
|
632
|
+
if ats.length == 1
|
633
|
+
tree_to_flor(ats[0], opts)
|
634
|
+
else
|
635
|
+
o << ats[0].first << ': '
|
636
|
+
tree_to_flor(ats[1], opts)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
ctrees.each do |ct|
|
641
|
+
o << "\n"
|
642
|
+
tree_to_flor(ct, opts.merge(ind: ' ' + i))
|
643
|
+
end unless opts[:chop]
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
def c_to_flor(t, opts)
|
648
|
+
|
649
|
+
o = opts[:o]
|
650
|
+
|
651
|
+
bs = (t[0] == '_arr') ? %w[ [ ] ] : %w[ { } ]
|
652
|
+
|
653
|
+
o << bs[0] # opening
|
654
|
+
|
655
|
+
atts, ctrees = t[1].partition { |ct| is_att_tree?(ct) }
|
656
|
+
|
657
|
+
ctrees.each_with_index do |ct, i|
|
658
|
+
o << ' '
|
659
|
+
t_to_flor(ct, opts)
|
660
|
+
o << ':' if bs[0] == '{' && i.even?
|
661
|
+
end
|
662
|
+
|
663
|
+
o << (ctrees.any? ? ' ' : '') << bs[1] # closing
|
664
|
+
end
|
665
|
+
|
666
|
+
public
|
667
|
+
|
668
|
+
|
523
669
|
#
|
524
670
|
# misc
|
525
671
|
|