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
data/lib/flor/unit/spooler.rb
CHANGED
data/lib/flor/unit/storage.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require 'zlib'
|
3
4
|
|
@@ -6,6 +7,14 @@ module Flor
|
|
6
7
|
|
7
8
|
class Storage
|
8
9
|
|
10
|
+
MESSAGE_COLUMNS = [
|
11
|
+
:domain, :exid, :point, :content,
|
12
|
+
:status, :ctime, :mtime, :cunit, :munit
|
13
|
+
].freeze
|
14
|
+
POINTER_COLUMNS = [
|
15
|
+
:domain, :exid, :nid, :type, :name, :value, :ctime, :cunit
|
16
|
+
].freeze
|
17
|
+
|
9
18
|
attr_reader :unit, :db, :models
|
10
19
|
|
11
20
|
attr_reader :mutex
|
@@ -30,9 +39,11 @@ module Flor
|
|
30
39
|
#p [ :disconnected, @db.object_id ]
|
31
40
|
end
|
32
41
|
|
33
|
-
def db_version
|
42
|
+
def db_version(opts={})
|
43
|
+
|
44
|
+
table, column = migration_table_and_column(opts)
|
34
45
|
|
35
|
-
(@db[
|
46
|
+
(@db[table].first rescue {})[column]
|
36
47
|
end
|
37
48
|
|
38
49
|
def migration_version
|
@@ -78,26 +89,28 @@ module Flor
|
|
78
89
|
opts = [ to, from, opts ].find { |e| e.is_a?(Hash) } || {}
|
79
90
|
opts[:target] ||= to if to.is_a?(Integer)
|
80
91
|
opts[:current] ||= from if from.is_a?(Integer)
|
92
|
+
|
93
|
+
opts[:table], opts[:column] = migration_table_and_column(opts)
|
81
94
|
#
|
82
95
|
# defaults for the migration version table:
|
83
96
|
# { table: :schema_info,
|
84
97
|
# column: :version }
|
85
98
|
|
86
99
|
skip =
|
100
|
+
opts[:sparse_migrations] ||
|
87
101
|
@unit.conf['db_sparse_migrations'] ||
|
88
|
-
@unit.conf['sto_sparse_migrations']
|
89
|
-
opts[:sparse_migrations]
|
102
|
+
@unit.conf['sto_sparse_migrations']
|
90
103
|
if skip && ! opts.has_key?(:allow_missing_migration_files)
|
91
104
|
opts[:allow_missing_migration_files] = true
|
92
105
|
end
|
93
106
|
|
94
107
|
dir =
|
108
|
+
opts[:migrations] ||
|
109
|
+
opts[:migration_dir] ||
|
95
110
|
@unit.conf['db_migrations'] ||
|
96
111
|
@unit.conf['db_migration_dir'] ||
|
97
112
|
@unit.conf['sto_migrations'] ||
|
98
113
|
@unit.conf['sto_migration_dir'] ||
|
99
|
-
opts[:migrations] ||
|
100
|
-
opts[:migration_dir] ||
|
101
114
|
Flor.migration_dir
|
102
115
|
|
103
116
|
synchronize do
|
@@ -106,9 +119,15 @@ module Flor
|
|
106
119
|
end
|
107
120
|
end
|
108
121
|
|
122
|
+
# Delete tables in the storage database that begin with "flor_"
|
123
|
+
# and have more than 2 columns (the Sequel schema_info table has 1 column
|
124
|
+
# as of this writing)
|
125
|
+
#
|
109
126
|
def delete_tables
|
110
127
|
|
111
|
-
@db.tables.each { |t|
|
128
|
+
@db.tables.each { |t|
|
129
|
+
@db[t].delete \
|
130
|
+
if t.to_s.match(/^flor_/) && @db[t].columns.size > 2 }
|
112
131
|
end
|
113
132
|
|
114
133
|
def load_execution(exid)
|
@@ -321,35 +340,39 @@ module Flor
|
|
321
340
|
n = Flor.tstamp
|
322
341
|
u = @unit.identifier
|
323
342
|
|
324
|
-
|
343
|
+
id =
|
344
|
+
synchronize(syn) do
|
325
345
|
|
326
|
-
|
346
|
+
stored, unstored = ms.partition { |m| m['mid'] }
|
327
347
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
348
|
+
#
|
349
|
+
# de-reserve any previously stored message, might happen
|
350
|
+
# for "terminated" messages that got queued back to let
|
351
|
+
# other messages get processed
|
332
352
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
353
|
+
@db[:flor_messages]
|
354
|
+
.where(id: stored.collect { |m| m['mid'] })
|
355
|
+
.update(status: 'created', mtime: n, munit: u) \
|
356
|
+
if stored.any?
|
337
357
|
|
338
|
-
|
339
|
-
|
358
|
+
#
|
359
|
+
# store new messages
|
340
360
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
361
|
+
@db[:flor_messages]
|
362
|
+
.import(
|
363
|
+
MESSAGE_COLUMNS,
|
364
|
+
unstored.map { |m|
|
365
|
+
[ Flor.domain(m['exid']), m['exid'], m['point'], to_blob(m),
|
366
|
+
'created', n, n, u, u ] }) \
|
367
|
+
if unstored.any?
|
368
|
+
|
369
|
+
@db[:flor_messages].max(:id)
|
370
|
+
end
|
350
371
|
|
351
372
|
@unit.wake_up
|
352
373
|
|
374
|
+
id
|
375
|
+
|
353
376
|
rescue => err
|
354
377
|
|
355
378
|
Thread.current[:sto_errored_items] = ms
|
@@ -501,25 +524,6 @@ module Flor
|
|
501
524
|
end
|
502
525
|
end
|
503
526
|
|
504
|
-
def put_task_pointer(msg, tname, tconf)
|
505
|
-
|
506
|
-
exid = msg['exid']
|
507
|
-
dom = Flor.domain(exid)
|
508
|
-
|
509
|
-
synchronize do
|
510
|
-
|
511
|
-
@db[:flor_pointers]
|
512
|
-
.insert(
|
513
|
-
domain: dom,
|
514
|
-
exid: exid,
|
515
|
-
nid: msg['nid'],
|
516
|
-
type: 'tasker',
|
517
|
-
name: tname,
|
518
|
-
ctime: Flor.tstamp,
|
519
|
-
cunit: @unit.identifier)
|
520
|
-
end
|
521
|
-
end
|
522
|
-
|
523
527
|
def fetch_next_time
|
524
528
|
|
525
529
|
t =
|
@@ -542,6 +546,18 @@ module Flor
|
|
542
546
|
|
543
547
|
protected
|
544
548
|
|
549
|
+
def migration_table_and_column(opts={})
|
550
|
+
|
551
|
+
[ (opts[:migration_table] ||
|
552
|
+
@unit.conf['db_migration_table'] ||
|
553
|
+
@unit.conf['sto_migration_table'] ||
|
554
|
+
:schema_info).to_sym,
|
555
|
+
(opts[:migration_column] ||
|
556
|
+
@unit.conf['db_migration_column'] ||
|
557
|
+
@unit.conf['sto_migration_column'] ||
|
558
|
+
:version).to_sym ]
|
559
|
+
end
|
560
|
+
|
545
561
|
def _commaify(o)
|
546
562
|
|
547
563
|
if Flor.is_regex_tree?(o)
|
@@ -570,14 +586,13 @@ module Flor
|
|
570
586
|
|
571
587
|
@db[:flor_messages]
|
572
588
|
.where(
|
573
|
-
id: messages.collect { |m| m['mid'] }.compact)
|
589
|
+
id: messages.collect { |m| m['mid'] }.uniq.compact)
|
574
590
|
.update(
|
575
591
|
status: 'consumed', mtime: n, munit: u)
|
576
592
|
|
577
593
|
@db[:flor_messages]
|
578
594
|
.import(
|
579
|
-
|
580
|
-
:status, :ctime, :mtime, :cunit, :munit ],
|
595
|
+
MESSAGE_COLUMNS,
|
581
596
|
messages
|
582
597
|
.select { |m|
|
583
598
|
! m['mid'] && POINTS_TO_ARCHIVE.include?(m['point']) }
|
@@ -593,19 +608,16 @@ module Flor
|
|
593
608
|
|
594
609
|
@db[:flor_messages]
|
595
610
|
.where(
|
596
|
-
id: messages.collect { |m| m['mid'] }.compact)
|
611
|
+
id: messages.collect { |m| m['mid'] }.uniq.compact)
|
597
612
|
.delete
|
598
613
|
end
|
599
614
|
end
|
600
615
|
|
601
616
|
def load_timers
|
602
617
|
|
603
|
-
now = Flor.tstamp
|
604
|
-
no = now[0, now.rindex('.')]
|
605
|
-
|
606
618
|
timers
|
607
619
|
.where(status: 'active')
|
608
|
-
.where { ntime <=
|
620
|
+
.where { ntime <= Flor.tstam }
|
609
621
|
.order(:ntime)
|
610
622
|
.all
|
611
623
|
|
@@ -675,9 +687,9 @@ module Flor
|
|
675
687
|
|
676
688
|
def update_pointers(exe, status, now)
|
677
689
|
|
678
|
-
# Q
|
679
|
-
#
|
680
|
-
#
|
690
|
+
# Q Should we archive old pointers?
|
691
|
+
# A Well, it might be better to only archive the execution and leave
|
692
|
+
# in there enough information...
|
681
693
|
|
682
694
|
exid = exe['exid']
|
683
695
|
|
@@ -703,23 +715,25 @@ module Flor
|
|
703
715
|
|
704
716
|
ts = node['tags']
|
705
717
|
ts.each { |t|
|
706
|
-
a << [ dom, exid, nid, 'tag', t, nil, now, u ] } if ts
|
718
|
+
a << [ dom, exid, nid, 'tag', t, nil, now, u, nil ] } if ts
|
707
719
|
|
708
720
|
vs = nid == '0' ? node['vars'] : nil
|
709
721
|
vs.each { |k, v|
|
710
722
|
case v; when Numeric, String, TrueClass, FalseClass, NilClass
|
711
|
-
a << [ dom, exid, '0', 'var', k, v.to_s, now, u ]
|
723
|
+
a << [ dom, exid, '0', 'var', k, v.to_s, now, u, nil ]
|
712
724
|
when Array, Hash
|
713
725
|
s = '(array)'; s = '(object)' if v.is_a?(Hash)
|
714
|
-
a << [ dom, exid, '0', 'var', k, s, now, u ]
|
726
|
+
a << [ dom, exid, '0', 'var', k, s, now, u, nil ]
|
715
727
|
else
|
716
|
-
a << [ dom, exid, '0', 'var', k, nil, now, u ]
|
728
|
+
a << [ dom, exid, '0', 'var', k, nil, now, u, nil ]
|
717
729
|
end } if vs
|
718
730
|
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
731
|
+
if ta = node['task']
|
732
|
+
tasker = ta['tasker']
|
733
|
+
name = ta['name']
|
734
|
+
content = { message: node['message'], atts: node['atts'] }
|
735
|
+
a << [ dom, exid, nid, 'tasker', tasker, name, now, u, content ]
|
736
|
+
end
|
723
737
|
|
724
738
|
a }
|
725
739
|
|
@@ -727,17 +741,35 @@ module Flor
|
|
727
741
|
.where(exid: exid)
|
728
742
|
.select(:nid, :type, :name)
|
729
743
|
.all
|
730
|
-
pointers.reject! { |_, _, ni, ty, na, _, _, _|
|
744
|
+
pointers.reject! { |_, _, ni, ty, na, _, _, _, _|
|
731
745
|
cps.find { |cp| cp[:nid] == ni && cp[:type] == ty && cp[:name] == na } }
|
732
746
|
#
|
733
747
|
# don't insert when already inserted
|
734
748
|
|
749
|
+
if pointer_columns.include?(:content)
|
750
|
+
pointers.each { |ptr|
|
751
|
+
c = ptr[8]; ptr[8] = to_blob(c) if c }
|
752
|
+
else
|
753
|
+
pointers.each { |ptr|
|
754
|
+
ptr.pop }
|
755
|
+
end
|
756
|
+
|
735
757
|
@db[:flor_pointers]
|
736
758
|
.import(
|
737
|
-
|
759
|
+
pointer_columns,
|
738
760
|
pointers)
|
739
761
|
end
|
740
762
|
|
763
|
+
def pointer_columns
|
764
|
+
|
765
|
+
@pointer_columns ||=
|
766
|
+
if @db[:flor_pointers].columns.include?(:content)
|
767
|
+
POINTER_COLUMNS + [ :content ]
|
768
|
+
else
|
769
|
+
POINTER_COLUMNS
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
741
773
|
def determine_type_and_schedule(message)
|
742
774
|
|
743
775
|
t, s = message['type'], message['string']
|
@@ -783,15 +815,27 @@ module Flor
|
|
783
815
|
def error(msg); @unit.logger.db_log(:error, msg); end
|
784
816
|
end
|
785
817
|
|
786
|
-
def
|
818
|
+
def derive_db
|
819
|
+
|
820
|
+
db = @unit.conf['sto_db']
|
821
|
+
|
822
|
+
return db if db
|
787
823
|
|
788
824
|
uri = @unit.conf['sto_uri']
|
789
825
|
|
790
|
-
|
791
|
-
|
792
|
-
|
826
|
+
fail ArgumentError.new("no 'sto_uri' conf, cannot connect to db") \
|
827
|
+
unless uri
|
828
|
+
|
829
|
+
return Kernel.const_get(uri) \
|
830
|
+
if uri.is_a?(String) && uri.match(/\A[A-Z]+\z/)
|
831
|
+
# for cases where uri == 'DB'
|
832
|
+
|
833
|
+
Sequel.connect(uri)
|
834
|
+
end
|
835
|
+
|
836
|
+
def connect
|
793
837
|
|
794
|
-
@db =
|
838
|
+
@db = derive_db
|
795
839
|
|
796
840
|
class << @db; attr_accessor :flor_unit; end
|
797
841
|
@db.flor_unit = @unit
|
data/lib/flor/unit/taskers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module Flor
|
3
4
|
|
@@ -28,6 +29,29 @@ module Flor
|
|
28
29
|
alias task_name taskname
|
29
30
|
|
30
31
|
def vars; @message['vars']; end
|
32
|
+
alias variables vars
|
33
|
+
|
34
|
+
def set_payload(h)
|
35
|
+
fail TypeError.new("not a hash but a #{fs.class}") unless h.is_a?(Hash)
|
36
|
+
@message['payload'] = h
|
37
|
+
end
|
38
|
+
alias set_fields set_payload
|
39
|
+
|
40
|
+
def set_vars(h)
|
41
|
+
fail TypeError.new("not a hash but a #{fs.class}") unless h.is_a?(Hash)
|
42
|
+
@message['vars'] = h
|
43
|
+
end
|
44
|
+
alias set_variables set_vars
|
45
|
+
|
46
|
+
#def merge_into_payload(h)
|
47
|
+
# @message['payload'].merge(h)
|
48
|
+
#end
|
49
|
+
#alias merge_into_fields merge_into_payload
|
50
|
+
#def merge_into_vars(h)
|
51
|
+
# @message['vars'].merge(h)
|
52
|
+
#end
|
53
|
+
#
|
54
|
+
# no for now, payload.merge(h) and vars.merge(h) do suffice
|
31
55
|
|
32
56
|
def execution
|
33
57
|
|
@@ -55,7 +79,11 @@ module Flor
|
|
55
79
|
|
56
80
|
def reply(message=@message, force=false)
|
57
81
|
|
58
|
-
|
82
|
+
fail ArgumentError.new(
|
83
|
+
"argument to reply must be a Hash but is #{message.class}"
|
84
|
+
) unless message.is_a?(Hash)
|
85
|
+
|
86
|
+
@ganger.return(derive_message(message)) if force || @ganger
|
59
87
|
|
60
88
|
[] # very important, return no further messages
|
61
89
|
end
|
@@ -65,6 +93,92 @@ module Flor
|
|
65
93
|
reply(
|
66
94
|
Flor.to_error_message(@message, error))
|
67
95
|
end
|
96
|
+
|
97
|
+
# So that #reply may be called with
|
98
|
+
# ```
|
99
|
+
# reply
|
100
|
+
# reply(@message)
|
101
|
+
# reply(payload: {})
|
102
|
+
# reply(ret: 123)
|
103
|
+
# reply(ret: 123, set: { a: 1 }, unset: [ :b ])
|
104
|
+
# ```
|
105
|
+
#
|
106
|
+
def derive_message(m)
|
107
|
+
|
108
|
+
exid = m['exid']
|
109
|
+
nid = m['nid']
|
110
|
+
pl = m['payload']
|
111
|
+
|
112
|
+
return m if Flor.is_exid?(exid) && Flor.is_nid?(nid) && pl.is_a?(Hash)
|
113
|
+
|
114
|
+
m = Flor.to_string_keyed_hash(m)
|
115
|
+
h = Flor.dup_message(@message)
|
116
|
+
ks = m.keys
|
117
|
+
|
118
|
+
if ks == [ 'payload' ]
|
119
|
+
|
120
|
+
h['payload'] = m['payload']
|
121
|
+
|
122
|
+
elsif (ks & %w[ ret set unset ]).size > 0
|
123
|
+
|
124
|
+
pl = (h['payload'] ||= {})
|
125
|
+
|
126
|
+
pl['ret'] = m['ret'] if m.has_key?('ret')
|
127
|
+
(m['set'] || {}).each { |k, v| pl[k] = v }
|
128
|
+
(m['unset'] || []).each { |k| pl.delete(k.to_s) }
|
129
|
+
|
130
|
+
else
|
131
|
+
|
132
|
+
h['payload'] = m
|
133
|
+
end
|
134
|
+
|
135
|
+
h
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# A BasicTasker with stages (pre / on / post)
|
140
|
+
#
|
141
|
+
class StagedBasicTasker < BasicTasker
|
142
|
+
|
143
|
+
def call_task
|
144
|
+
|
145
|
+
call_one_of(:pre_task)
|
146
|
+
call_one_of(:on_task, :task)
|
147
|
+
end
|
148
|
+
|
149
|
+
def call_detask
|
150
|
+
|
151
|
+
call_one_of(:pre_detask, :pre_cancel)
|
152
|
+
call_one_of(:on_detask, :on_cancel, :detask, :cancel)
|
153
|
+
end
|
154
|
+
|
155
|
+
protected
|
156
|
+
|
157
|
+
def call_one_of(*ms)
|
158
|
+
|
159
|
+
m = ms.flatten.find { |mm| respond_to?(mm) }
|
160
|
+
|
161
|
+
send(m) if m
|
162
|
+
end
|
163
|
+
|
164
|
+
def reply(message=@message, force=false)
|
165
|
+
|
166
|
+
fail ArgumentError.new(
|
167
|
+
"argument to reply must be a Hash but is #{message.class}"
|
168
|
+
) unless message.is_a?(Hash)
|
169
|
+
|
170
|
+
pt = @message['point']
|
171
|
+
|
172
|
+
ms = [ "post_#{pt}" ]; ms << :post_cancel if pt == 'detask'
|
173
|
+
#
|
174
|
+
call_one_of(ms)
|
175
|
+
|
176
|
+
msg = derive_message(message)
|
177
|
+
|
178
|
+
@ganger.return(msg) if force || @ganger
|
179
|
+
|
180
|
+
[] # very important, return no further messages
|
181
|
+
end
|
68
182
|
end
|
69
183
|
end
|
70
184
|
|