flor 1.2.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e89a3c4accc6ee1eca033031352f4c6d20c9b42ffbcb44aebe3cca04b59bc128
4
- data.tar.gz: 30914f85dfb1f76de1877cdb60e977eff73cb1ee31d9dfa7b893160799b4c162
3
+ metadata.gz: 298a6b2c9d3752b561ee8933ae00ed7a3f63682fb758dbe899097c6f7f56c00d
4
+ data.tar.gz: 3e2602737b9de7a452549d0f8ed34752618b1322a5508d178abe6559d549c045
5
5
  SHA512:
6
- metadata.gz: 91cbcbbebccc7209554f49645a43876bf7f2743a77eac4a64ab3daf7f5fbfb8f2e7d566f6ffc03c932222aa2daf82e5674fd52a653bddd8b390b27cbb4714e1c
7
- data.tar.gz: 174730b60ab5366c9cae335644ace73722ff52dc34477754020817c630dfabe1f6710846e437bbb936cb76fb4922f04d1dc2ffd2fde64f4c80924bd3dd7a629f
6
+ metadata.gz: 28ae10c78676391537dde7cd7e0082338650c6aeba60fbcffa2ca5a4cb2dd2f168d7ff61019472c5f6f3d2216cabfe6e9bccb7cdae4856b513e0663f4d4ec362
7
+ data.tar.gz: 6379738cddfc5b74d37a30fa23260924649866b49dc670f37a0540a47a5079062288851ce07306350e227d73d0fd873f2199c3ea01b3399bce61572b8cebe497
data/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ## flor 1.4.0 released 2021-11-10
6
+
7
+ * Add :tree to Execution#to_h
8
+ * Scaffold bin/flotojson
9
+
10
+
11
+ ## flor 1.3.1 released 2021-04-19
12
+
13
+ * Fix flor_pointers var deletion mechanism (type = ' var ')
14
+
15
+
16
+ ## flor 1.3.0 released 2021-04-13
17
+
18
+ * Insert a row flor_pointers for 'failure'
19
+
20
+
21
+ ## flor 1.2.2 released 2021-03-29
22
+
23
+ * Include data in flor_pointers
24
+ * Ensure flor_pointers name is a string
25
+
26
+
5
27
  ## flor 1.2.1 released 2021-03-22
6
28
 
7
29
  * If conf sto_db_logger is false, do not attach a logger to the db connection
@@ -149,7 +149,7 @@ class Flor::Node
149
149
  tree = lookup_tree(Flor.parent_nid(nid))
150
150
  return tree[1][cid] if tree
151
151
 
152
- #tree = lookup_tree(Flor.parent_nid(nid, true))
152
+ #tree = lookup_tree(Flor.parent_nid(nid, remove_subnid=true))
153
153
  #return tree[1][cid] if tree
154
154
  #
155
155
  # might become necessary at some point
@@ -5,7 +5,7 @@ class Flor::Procedure < Flor::Node
5
5
  # "Returning vars" variables to pass back to pass upon reply.
6
6
  # In the 'receive' messages, it's a hash under the key 'rvars'.
7
7
  #
8
- RVARS = %w[ idx ]
8
+ RVARS = %w[ idx ].freeze
9
9
 
10
10
  # Attributes that when given alone are turned to "true" attributes.
11
11
  #
@@ -13,7 +13,7 @@ class Flor::Procedure < Flor::Node
13
13
  #
14
14
  # The transformation occurs in Flor::Pro::Att ("_att").
15
15
  #
16
- TRUE_ATTS = %w[ flank off disabled ]
16
+ TRUE_ATTS = %w[ flank off disabled ].freeze
17
17
 
18
18
  class << self
19
19
 
@@ -550,6 +550,8 @@ class Flor::Procedure < Flor::Node
550
550
  wrap_reply
551
551
  end
552
552
 
553
+ IF_UNLESS = %w[ _if _unless ].freeze
554
+
553
555
  # Grab on_error proc from incoming payload and stores it into parent node.
554
556
  #
555
557
  # Has no effect if there is no parent node.
@@ -562,7 +564,7 @@ class Flor::Procedure < Flor::Node
562
564
  @node; loop do
563
565
  pnode = parent_node(pnode)
564
566
  return unless pnode
565
- break unless %w[ _if _unless ].include?(pnode['heap'])
567
+ break unless IF_UNLESS.include?(pnode['heap'])
566
568
  end
567
569
 
568
570
  flavour = "on_#{key}"
@@ -598,6 +600,8 @@ class Flor::Procedure < Flor::Node
598
600
  wrap('point' => 'entered', 'nid' => nid, 'tags' => ret)
599
601
  end
600
602
 
603
+ WRAP_KEYS = %w[ error cancel timeout ].freeze
604
+
601
605
  def wrap(h={})
602
606
 
603
607
  m = {}
@@ -642,7 +646,7 @@ class Flor::Procedure < Flor::Node
642
646
  # was considering passing the whole vars back (as 'varz'), but
643
647
  # it got in the way... and it might be heavy
644
648
 
645
- %w[ error cancel timeout ]
649
+ WRAP_KEYS
646
650
  .each { |k|
647
651
  co = @node["child_on_#{k}"]
648
652
  next unless co
data/lib/flor/log.rb CHANGED
@@ -343,7 +343,7 @@ module Flor
343
343
  o.puts(tree_to_s(node.lookup_tree(nid), nid, out: o)) if node
344
344
 
345
345
  o.puts "#{_c.dg}node:#{_c.yl}"
346
- o.puts YAML.dump(n.merge('tree' => '(above)'))
346
+ o.puts n ? YAML.dump(n.merge('tree' => '(above)')) : 'nil'
347
347
 
348
348
  o.puts "#{_c.dg}nodes:#{_c.yl}"
349
349
  o.puts nods_to_s(executor, m, opts)
data/lib/flor/parser.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Flor
3
4
 
4
5
  def self.parse(input, fname=nil, opts={})
@@ -727,3 +728,4 @@ fail "don't know how to invert #{operation.inspect}" # FIXME
727
728
  sio.string
728
729
  end
729
730
  end
731
+
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # flotojson.rb
4
+
5
+ require 'flor'
6
+
7
+ FLAGS_WITH_VALUE = []
8
+
9
+ flags = {}
10
+ files = []
11
+
12
+ if (ARGV & [ '-h', '--help']).any?
13
+ puts
14
+ puts "bin/flotojson [flags] filename"
15
+ puts
16
+ puts " turns a flor .flo process definition to its tree representation"
17
+ puts
18
+ puts " flags:"
19
+ puts " --pp pretty prints instead of dumping as JSON"
20
+ puts
21
+ exit 0
22
+ end
23
+
24
+ args = ARGV.dup
25
+
26
+ loop do
27
+
28
+ a = args.shift; break unless a
29
+
30
+ if a.size > 1 && a[0, 1] == '-'
31
+ flags[a] = FLAGS_WITH_VALUE.include?(a) ? a.shift : true
32
+ else
33
+ files << a
34
+ end
35
+ end
36
+
37
+ #STDERR.puts flags.inspect
38
+ #STDERR.puts files.inspect
39
+
40
+ # t =
41
+ # tree.is_a?(String) ?
42
+ # Flor.parse(tree, opts[:fname] || opts[:path], opts) :
43
+ # tree
44
+ #
45
+ # unless t
46
+ #
47
+ # #h = opts.merge(prune: false, rewrite: false, debug: 0)
48
+ # #Raabro.pp(Flor.parse(tree, h[:fname], h))
49
+ # # TODO re-parse and indicate what went wrong...
50
+ #
51
+ # fail ArgumentError.new(
52
+ # "flow parsing failed: " + tree.inspect[0, 35] + '...')
53
+ # end
54
+
55
+ fname = files.first
56
+ content = File.read(fname)
57
+ tree = Flor.parse(content, fname, {})
58
+
59
+ if flags['--pp']
60
+ pp tree
61
+ else
62
+ puts JSON.dump(tree)
63
+ end
64
+
@@ -20,7 +20,29 @@ module Flor
20
20
  #end
21
21
 
22
22
  def nodes; data['nodes']; end
23
+
23
24
  def zero_node; nodes['0']; end
25
+
26
+ # Returns the nids, the lower in the tree, the earlier in the returned
27
+ # array.
28
+ #
29
+ def sorted_nids
30
+
31
+ nodes.keys
32
+ .inject([]) { |a, nid|
33
+ l = nid.split('_').length
34
+ (a[l] ||= []) << nid
35
+ a }
36
+ .compact
37
+ .collect(&:sort)
38
+ .flatten(1)
39
+ end
40
+
41
+ def lowest_node
42
+
43
+ nodes[sorted_nids.first]
44
+ end
45
+
24
46
  def closing_messages; data['closing_messages']; end
25
47
 
26
48
  def execution(reload=false); self; end
@@ -47,14 +69,16 @@ module Flor
47
69
 
48
70
  def full_tree
49
71
 
50
- tree = nodes['0']['tree']
72
+ nids = sorted_nids
73
+ nid0 = nids.shift
51
74
 
52
- #nodes.each do |nid, n|
53
- # next if nid == '0'
54
- # t = n['tree']; next unless t
55
- #end
56
- #
57
- # FIXME
75
+ return nil unless nid0
76
+
77
+ tree = Flor.dup(nodes[nid0]['tree'])
78
+
79
+ nids.each { |nid|
80
+ next unless nid.split('_', 2).first == nid0
81
+ replace_sub_tree(tree, nid, nodes[nid]['tree']) }
58
82
 
59
83
  tree
60
84
  end
@@ -80,21 +104,22 @@ module Flor
80
104
  cs = m[:counts] = {}
81
105
  is = m[:nids] = { tasks: [], failures: [] }
82
106
 
83
- fs = 0
84
- ts = 0
107
+ cs[:failures] = 0
108
+ cs[:tasks] = 0
109
+ cs[:nodes] = nodes.count
110
+ #
85
111
  nodes.each do |k, v|
86
112
  if v['task']
87
- ts += 1
113
+ cs[:tasks] += 1
88
114
  is[:tasks] << k
89
115
  end
90
116
  if v['failure']
91
- fs += 1
117
+ cs[:failures] += 1
92
118
  is[:failures] << k
93
119
  end
94
120
  end
95
- cs[:nodes] = nodes.count
96
- cs[:failures] = fs
97
- cs[:tasks] = ts
121
+
122
+ h[:tree] = full_tree
98
123
 
99
124
  h
100
125
  end
@@ -149,6 +174,30 @@ module Flor
149
174
  lookup_node(query, opts)['nid']
150
175
  end
151
176
 
177
+ protected
178
+
179
+ def replace_sub_tree(tree, nid, t)
180
+
181
+ return unless t
182
+ return if nid.index('-') # stay vanilla
183
+
184
+ snid = nid.split('_').collect(&:to_i)[1..-1]
185
+ a = get_child_array(tree, snid)
186
+
187
+ return unless a # shouldn't we fail?
188
+
189
+ a[snid.first] = Flor.dup(t)
190
+ end
191
+
192
+ def get_child_array(tree, snid)
193
+
194
+ return nil if tree.nil?
195
+ return nil if snid.length < 1
196
+ return nil unless tree[1].is_a?(Array)
197
+ return tree[1] if snid.length == 1
198
+ n = snid.shift; get_child_array(tree[1][n], snid)
199
+ end
200
+
152
201
  class << self
153
202
 
154
203
  def by_status(s)
@@ -242,18 +242,18 @@ module Flor
242
242
  end
243
243
  end
244
244
 
245
+ RETURN_KEYS = %w[ exid nid payload tasker cause ].freeze
246
+
245
247
  def return(message)
246
248
 
247
- m =
249
+ queue(
248
250
  if message['point'] == 'failed'
249
251
  message
250
252
  else
251
253
  message
252
- .select { |k, _| %w[ exid nid payload tasker cause ].include?(k) }
254
+ .select { |k, _| RETURN_KEYS.include?(k) }
253
255
  .merge!('point' => 'return')
254
- end
255
-
256
- queue(m)
256
+ end)
257
257
 
258
258
  nil
259
259
  end
@@ -432,7 +432,7 @@ module Flor
432
432
  ex ? ex.execution : nil
433
433
  end
434
434
 
435
- DUMP_KEYS = %w[ timestamp executions timers traps pointers ]
435
+ DUMP_KEYS = %w[ timestamp executions timers traps pointers ].freeze
436
436
 
437
437
  # Dumps all or some of the executions to a JSON string.
438
438
  # See Scheduler#load for importing.
@@ -598,6 +598,8 @@ module Flor
598
598
  puts(on_start_exc(ex))
599
599
  end
600
600
 
601
+ PREP_KEYS = %w[ exid name nid payload on_receive_last ].freeze
602
+
601
603
  def prepare_message(point, args)
602
604
 
603
605
  h = args
@@ -612,7 +614,7 @@ module Flor
612
614
  opts = {}
613
615
 
614
616
  h.each do |k, v|
615
- if %w[ exid name nid payload on_receive_last ].include?(k)
617
+ if PREP_KEYS.include?(k)
616
618
  msg[k] = v
617
619
  else
618
620
  opts[k.to_sym] = v
@@ -12,8 +12,9 @@ module Flor
12
12
  :status, :ctime, :mtime, :cunit, :munit
13
13
  ].freeze
14
14
  POINTER_COLUMNS = [
15
- :domain, :exid, :nid, :type, :name, :value, :ctime, :cunit
16
- ].freeze
15
+ :domain, :exid, :nid, :type, :name, :value, :ctime, :cunit,
16
+ :content
17
+ ].freeze
17
18
 
18
19
  attr_reader :unit, :db, :models
19
20
 
@@ -219,6 +220,9 @@ module Flor
219
220
  raise err
220
221
  end
221
222
 
223
+ CRECON_STATUSES = %w[ created consumed ].freeze
224
+ RESCON_STATUSES = %w[ reserved consumed ].freeze
225
+
222
226
  def load_messages(exe_count)
223
227
 
224
228
  exe_count += 2
@@ -229,12 +233,12 @@ module Flor
229
233
  _exids_being_processed =
230
234
  @db[:flor_messages]
231
235
  .select(:exid)
232
- .exclude(status: %w[ created consumed ])
236
+ .exclude(status: CRECON_STATUSES)
233
237
  _exids =
234
238
  @db[:flor_messages]
235
239
  .select(:exid)
236
240
  .exclude(exid: _exids_being_processed)
237
- .exclude(status: %w[ reserved consumed ])
241
+ .exclude(status: RESCON_STATUSES)
238
242
  .limit(exe_count)
239
243
  @db[:flor_messages]
240
244
  .where(exid: _exids, status: 'created')
@@ -317,7 +321,7 @@ module Flor
317
321
  []
318
322
  end
319
323
 
320
- POINTS_TO_ARCHIVE = %w[ terminated failed ceased ]
324
+ POINTS_TO_ARCHIVE = %w[ terminated failed ceased ].freeze
321
325
 
322
326
  def consume(messages)
323
327
 
@@ -685,6 +689,8 @@ module Flor
685
689
  # done in update_pointers
686
690
  end
687
691
 
692
+ FP_TYPES = %w[ var ].freeze
693
+
688
694
  def update_pointers(exe, status, now)
689
695
 
690
696
  # Q Should we archive old pointers?
@@ -700,7 +706,7 @@ module Flor
700
706
 
701
707
  @db[:flor_pointers]
702
708
  .where(exid: exid)
703
- .where(Sequel.|({ type: %w[ var ] }, Sequel.~(nid: exe['nodes'].keys)))
709
+ .where(Sequel.|({ type: FP_TYPES }, Sequel.~(nid: exe['nodes'].keys)))
704
710
  .delete
705
711
  #
706
712
  # Delete all pointer to vars, their value might have changed,
@@ -713,28 +719,57 @@ module Flor
713
719
  pointers = exe['nodes']
714
720
  .inject([]) { |a, (nid, node)|
715
721
 
722
+ # add a pointer for each tag
723
+
716
724
  ts = node['tags']
717
725
  ts.each { |t|
718
726
  a << [ dom, exid, nid, 'tag', t, nil, now, u, nil ] } if ts
719
727
 
728
+ # add a pointer for each var (if nid == '0')
729
+
720
730
  vs = nid == '0' ? node['vars'] : nil
721
731
  vs.each { |k, v|
722
732
  case v; when Numeric, String, TrueClass, FalseClass, NilClass
723
- a << [ dom, exid, '0', 'var', k, v.to_s, now, u, nil ]
733
+ a << [ dom, exid, '0', 'var', k, v.to_s, now, u, v ]
724
734
  when Array, Hash
725
735
  s = '(array)'; s = '(object)' if v.is_a?(Hash)
726
- a << [ dom, exid, '0', 'var', k, s, now, u, nil ]
736
+ a << [ dom, exid, '0', 'var', k, s, now, u, v ]
727
737
  else
728
- a << [ dom, exid, '0', 'var', k, nil, now, u, nil ]
738
+ a << [ dom, exid, '0', 'var', k, nil, now, u, v ]
729
739
  end } if vs
730
740
 
741
+ # add a pointer for the task if any
742
+
731
743
  if ta = node['task']
732
744
  tasker = ta['tasker']
733
- name = ta['name']
745
+ n = ta['name']; name = n.is_a?(String) ? n : JSON.dump(n)
734
746
  content = { message: node['message'], atts: node['atts'] }
735
747
  a << [ dom, exid, nid, 'tasker', tasker, name, now, u, content ]
736
748
  end
737
749
 
750
+ # add a pointer for the error if any
751
+
752
+ if fa = node['failure']
753
+
754
+ #puts "-" * 80; pp node; puts "-" * 80
755
+ a <<
756
+ if er = fa['error']
757
+ ni = fa['from'] || nid # not nid /!\
758
+ nam = "#{er['kla']} l#{er['lin']}"
759
+ val = er['msg']
760
+ con = { error: fa, nid: ni }
761
+ [ dom, exid, ni, 'failure', nam, val, now, u, con ]
762
+ else
763
+ nam = fa['tasker'] || 'failure'
764
+ val = [ fa['attl'] || [], fa['attd'] || {} ]
765
+ .collect(&:inspect).join(' ')
766
+ con = { error: fa, nid: nid }
767
+ [ dom, exid, nid, 'failure', nam, val, now, u, con ]
768
+ end
769
+ end
770
+
771
+ # done
772
+
738
773
  a }
739
774
 
740
775
  cps = @db[:flor_pointers] # current pointers
@@ -746,29 +781,22 @@ module Flor
746
781
  #
747
782
  # don't insert when already inserted
748
783
 
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
784
+ pointers.each { |ptr| c = ptr[8]; ptr[8] = to_blob(c) if c }
756
785
 
757
786
  @db[:flor_pointers]
758
787
  .import(
759
- pointer_columns,
788
+ POINTER_COLUMNS,
760
789
  pointers)
761
790
  end
762
791
 
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
792
+ #def pointer_columns
793
+ # @pointer_columns ||=
794
+ # if @db[:flor_pointers].columns.include?(:content)
795
+ # POINTER_COLUMNS + [ :content ]
796
+ # else
797
+ # POINTER_COLUMNS
798
+ # end
799
+ #end
772
800
 
773
801
  def determine_type_and_schedule(message)
774
802
 
data/lib/flor.rb CHANGED
@@ -16,7 +16,7 @@ require 'dense'
16
16
 
17
17
  module Flor
18
18
 
19
- VERSION = '1.2.1'
19
+ VERSION = '1.4.0'
20
20
  end
21
21
 
22
22
  require 'flor/colours'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-22 00:00:00.000000000 Z
11
+ date: 2021-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: munemo
@@ -249,6 +249,7 @@ files:
249
249
  - lib/flor/to_string.rb
250
250
  - lib/flor/tools/env.rb
251
251
  - lib/flor/tools/firb.rb
252
+ - lib/flor/tools/flotojson.rb
252
253
  - lib/flor/tools/shell.rb
253
254
  - lib/flor/tools/shell_out.rb
254
255
  - lib/flor/tt.rb