flor 0.9.5 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. data/CHANGELOG.md +10 -0
  2. data/Makefile +13 -5
  3. data/README.md +0 -35
  4. data/flor.gemspec +1 -0
  5. data/lib/flor.rb +6 -24
  6. data/lib/flor/changes.rb +26 -0
  7. data/lib/flor/colours.rb +65 -31
  8. data/lib/flor/conf.rb +84 -54
  9. data/lib/flor/core.rb +0 -23
  10. data/lib/flor/core/executor.rb +12 -42
  11. data/lib/flor/core/node.rb +19 -24
  12. data/lib/flor/core/procedure.rb +13 -24
  13. data/lib/flor/core/texecutor.rb +10 -28
  14. data/lib/flor/deep.rb +152 -0
  15. data/lib/flor/djan.rb +200 -0
  16. data/lib/flor/dollar.rb +0 -24
  17. data/lib/flor/errors.rb +0 -24
  18. data/lib/flor/flor.rb +43 -296
  19. data/lib/flor/id.rb +90 -0
  20. data/lib/flor/log.rb +12 -35
  21. data/lib/flor/migrations/0002_cunit_and_munit.rb +86 -0
  22. data/lib/flor/parser.rb +40 -46
  23. data/lib/flor/pcore/_arr.rb +0 -24
  24. data/lib/flor/pcore/_atom.rb +0 -24
  25. data/lib/flor/pcore/_att.rb +3 -25
  26. data/lib/flor/pcore/_dump.rb +0 -24
  27. data/lib/flor/pcore/_err.rb +0 -24
  28. data/lib/flor/pcore/_happly.rb +0 -24
  29. data/lib/flor/pcore/_obj.rb +0 -24
  30. data/lib/flor/pcore/_skip.rb +0 -24
  31. data/lib/flor/pcore/arith.rb +0 -24
  32. data/lib/flor/pcore/break.rb +0 -24
  33. data/lib/flor/pcore/case.rb +127 -0
  34. data/lib/flor/pcore/cmp.rb +0 -24
  35. data/lib/flor/pcore/cond.rb +24 -24
  36. data/lib/flor/pcore/cursor.rb +0 -24
  37. data/lib/flor/pcore/define.rb +0 -24
  38. data/lib/flor/pcore/fail.rb +0 -24
  39. data/lib/flor/pcore/if.rb +39 -0
  40. data/lib/flor/pcore/loop.rb +0 -24
  41. data/lib/flor/pcore/map.rb +0 -24
  42. data/lib/flor/pcore/match.rb +0 -24
  43. data/lib/flor/pcore/move.rb +0 -24
  44. data/lib/flor/pcore/noeval.rb +0 -24
  45. data/lib/flor/pcore/noret.rb +0 -24
  46. data/lib/flor/pcore/push.rb +1 -25
  47. data/lib/flor/pcore/rand.rb +59 -0
  48. data/lib/flor/pcore/sequence.rb +0 -24
  49. data/lib/flor/pcore/set.rb +0 -24
  50. data/lib/flor/pcore/stall.rb +0 -24
  51. data/lib/flor/pcore/until.rb +0 -24
  52. data/lib/flor/pcore/val.rb +0 -24
  53. data/lib/flor/punit/cancel.rb +0 -24
  54. data/lib/flor/punit/cmap.rb +0 -24
  55. data/lib/flor/punit/concurrence.rb +54 -24
  56. data/lib/flor/punit/every.rb +0 -24
  57. data/lib/flor/punit/graft.rb +41 -0
  58. data/lib/flor/punit/on.rb +0 -24
  59. data/lib/flor/punit/schedule.rb +0 -24
  60. data/lib/flor/punit/signal.rb +0 -24
  61. data/lib/flor/punit/sleep.rb +0 -24
  62. data/lib/flor/punit/task.rb +0 -26
  63. data/lib/flor/punit/trace.rb +0 -24
  64. data/lib/flor/punit/trap.rb +0 -24
  65. data/lib/flor/to_string.rb +4 -25
  66. data/lib/flor/tools/env.rb +0 -23
  67. data/lib/flor/tools/shell.rb +810 -0
  68. data/lib/flor/unit.rb +0 -23
  69. data/lib/flor/unit/executor.rb +35 -31
  70. data/lib/flor/unit/ganger.rb +9 -34
  71. data/lib/flor/unit/hooker.rb +5 -25
  72. data/lib/flor/unit/journal.rb +0 -23
  73. data/lib/flor/unit/loader.rb +63 -94
  74. data/lib/flor/unit/logger.rb +8 -27
  75. data/lib/flor/unit/models.rb +0 -24
  76. data/lib/flor/unit/models/execution.rb +13 -24
  77. data/lib/flor/unit/models/pointer.rb +0 -24
  78. data/lib/flor/unit/models/timer.rb +0 -24
  79. data/lib/flor/unit/models/trace.rb +0 -24
  80. data/lib/flor/unit/models/trap.rb +0 -24
  81. data/lib/flor/unit/scheduler.rb +157 -128
  82. data/lib/flor/unit/storage.rb +224 -167
  83. data/lib/flor/unit/taskers.rb +38 -25
  84. data/lib/flor/unit/waiter.rb +7 -26
  85. data/lib/flor/unit/wlist.rb +8 -24
  86. metadata +28 -7
  87. data/fail.txt +0 -16
  88. data/intercepted.txt +0 -123
  89. data/lib/flor/pcore/ife.rb +0 -56
  90. data/lib/flor/tools/repl.rb +0 -231
  91. data/out.txt +0 -206
@@ -1,26 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
1
 
25
2
  module Flor
26
3
 
@@ -103,6 +80,8 @@ module Flor
103
80
  def db_log(level, msg)
104
81
 
105
82
  return unless @unit.conf['log_sto']
83
+ #return unless msg.match(/flor_timers/)
84
+ #p Time.now
106
85
 
107
86
  _c = Flor.colours(out: @out)
108
87
 
@@ -140,17 +119,19 @@ module Flor
140
119
  @out.puts(s.string)
141
120
  end
142
121
 
143
- def log_run_end(executor, t0)
122
+ def log_run_end(executor, tstamp, duration)
144
123
 
145
124
  return unless @unit.conf['log_run']
146
125
 
147
126
  execution = executor.execution
127
+ exid = executor.exid
128
+
148
129
  _c = Flor.colours(out: @out)
149
130
  s = StringIO.new
150
131
 
151
132
  s << _c.dg
152
- s << " | run ends #{self.class} #{self.object_id} #{@exid}"
153
- s << "\n | "; s << { took: Time.now - t0 }.inspect
133
+ s << " | run ends #{self.class} #{self.object_id} #{exid}"
134
+ s << "\n | "; s << { started: tstamp, took: duration }.inspect
154
135
  s << "\n | "; s << {
155
136
  thread: Thread.current.object_id,
156
137
  consumed: executor.consumed.count,
@@ -165,7 +146,7 @@ module Flor
165
146
  if @unit.archive
166
147
  s << "\n | "
167
148
  s << {
168
- archive_size: @unit.archive[@exid].size
149
+ archive_size: (@unit.archive[exid].size rescue '???')
169
150
  }.inspect
170
151
  end
171
152
  s << "\n \\--- ."
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -43,6 +19,19 @@ module Flor
43
19
  .find { |n| n['failure'] && n['status'] != 'triggered-on-error' }
44
20
  end
45
21
 
22
+ def full_tree
23
+
24
+ tree = nodes['0']['tree']
25
+
26
+ nodes.each do |nid, n|
27
+ next if nid == '0'
28
+ t = n['tree']; next unless t
29
+ # TODO
30
+ end
31
+
32
+ tree
33
+ end
34
+
46
35
  # class methods
47
36
 
48
37
  def self.by_status(s)
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -1,27 +1,3 @@
1
- #--
2
- # Copyright (c) 2015-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
25
1
 
26
2
  module Flor
27
3
 
@@ -67,21 +43,30 @@ module Flor
67
43
  @hooker.add('wlist', Flor::WaitList)
68
44
 
69
45
  @heart_rate = @conf[:sch_heart_rate] || 0.3
70
- @reload_frequency = @conf[:sch_reload_frequency] || 60
71
- @max_executors = @conf[:sch_max_executors] || 1
46
+ @reload_after = @conf[:sch_reload_after] || 60
47
+ #
48
+ @wake_up = true
49
+ @next_time = nil
50
+ @reloaded_at = Time.now
72
51
 
73
- @mutex = Mutex.new
52
+ @msg_max_res_time = @conf[:sch_msg_max_res_time] || 10 * 60
74
53
 
75
- @reloaded_at = nil
76
- @timers = []
77
- @exids = []
54
+ @idle_count = 0
78
55
 
56
+ @max_executors = @conf[:sch_max_executors] || 1
57
+ #
79
58
  @executors = []
80
59
 
81
- @archive = nil # used, so far, only for testing
82
-
83
60
  c = @conf['constant']
61
+ #
84
62
  Kernel.const_set(c, self) if c
63
+
64
+ @archive = nil # used, so far, only for testing
65
+ end
66
+
67
+ def name
68
+
69
+ @conf['unit'] || @conf['uni_name'] || 'u0'
85
70
  end
86
71
 
87
72
  def storage_mutex
@@ -91,7 +76,20 @@ module Flor
91
76
 
92
77
  def identifier
93
78
 
94
- @identifier ||= 's' + Digest::MD5.hexdigest(self.object_id.to_s)[0, 5]
79
+ @identifier ||=
80
+ begin
81
+ ai =
82
+ Socket.ip_address_list.find { |a| a.ipv4_private? } ||
83
+ Socket.ip_address_list.find { |a| a.ip_address != '::1' }
84
+ ip =
85
+ ai ? ai.ip_address : '::1'
86
+ [
87
+ 'sch', self.name,
88
+ 'i' + ip,
89
+ 'p' + Process.pid.to_s,
90
+ 'o' + (self.object_id % 100_000).to_s(32)
91
+ ].join('-')
92
+ end
95
93
  end
96
94
 
97
95
  def has_tasker?(exid, tname)
@@ -157,23 +155,36 @@ module Flor
157
155
  else
158
156
 
159
157
  Thread.new do
160
- #p [ :unit_scheduler, :thread, Thread.current.object_id ]
158
+
161
159
  loop do
162
160
 
163
161
  begin
164
162
 
165
- t0 = Time.now
166
-
167
163
  Thread.stop if @thread_status == :stop
168
164
  break if @thread_status == :shutdown
169
165
 
170
- reload
171
- trigger_timers
172
- trigger_executions
166
+ t0 = Time.now
167
+
168
+ if should_wake_up?
169
+
170
+ unreserve_messages
171
+
172
+ trigger_timers
173
+ trigger_executions
173
174
 
174
- sleep [ @heart_rate - (Time.now - t0), 0 ].max
175
+ reload_next_time
176
+ reload_wake_up
177
+ @reloaded_at = Time.now
178
+
179
+ elsif @executors.empty?
180
+
181
+ @idle_count += 1
182
+ notify(nil, make_idle_message)
183
+ end
184
+
185
+ sleep [ @heart_rate - (Time.now - t0), 0 ].max #\
186
+ #unless should_wake_up?
175
187
 
176
- #rescue => er
177
188
  rescue Exception => ex
178
189
 
179
190
  puts on_start_exc(ex)
@@ -228,16 +239,16 @@ module Flor
228
239
  end
229
240
 
230
241
  fail ArgumentError.new(
231
- "flow not found in #{Flor.truncate(source_or_path, 35).inspect}"
242
+ "flow not found in #{Flor.truncate_string(source_or_path, 35).inspect}"
232
243
  ) unless source # will anyway fail badly if src is a tree (array of ...)
233
244
 
234
245
  @archive ||= {} if opts[:archive]
235
246
  # all subsequent launches will be `archive: true` ...
236
247
 
237
- unit = opts[:unit] || @conf['unit'] || 'u0'
238
-
239
248
  @logger.log_src(source, opts)
240
249
 
250
+ unit = opts[:unit] || self.name
251
+
241
252
  exid = Flor.generate_exid(domain, unit)
242
253
  msg = Flor.make_launch_msg(exid, source, opts)
243
254
 
@@ -260,17 +271,16 @@ module Flor
260
271
  end
261
272
  end
262
273
 
263
- def prepare_message(point, h)
264
-
265
- msg = { 'point' => point }
266
- [ :exid, :name, :nid, :payload ].each { |k| msg[k.to_s] = h[k] }
274
+ def return(message)
267
275
 
268
- fail ArgumentError.new('missing :exid key') \
269
- unless msg['exid'].is_a?(String)
270
- fail ArgumentError.new('missing :name string key') \
271
- if point == 'signal' && ! msg['name'].is_a?(String)
276
+ queue({
277
+ 'point' => 'return',
278
+ 'exid' => message['exid'],
279
+ 'nid' => message['nid'],
280
+ 'payload' => message['payload'],
281
+ 'tasker' => message['tasker'] })
272
282
 
273
- msg
283
+ nil
274
284
  end
275
285
 
276
286
  def cancel(h)
@@ -285,21 +295,30 @@ module Flor
285
295
  queue(prepare_message('signal', h), h)
286
296
  end
287
297
 
288
- def put_timer(message)
298
+ def re_apply(h)
289
299
 
290
- timer = @storage.put_timer(message)
300
+ queue(prepare_message('cancel', h.merge(re_apply: true)), h)
301
+ end
302
+
303
+ def put_timer(message)
291
304
 
292
- @mutex.synchronize { @timers.push(timer).sort_by!(&:ntime) }
305
+ #timer = @storage.put_timer(message)
306
+ #@mutex.synchronize { @timers.push(timer).sort_by!(&:ntime) }
307
+ @storage.put_timer(message)
293
308
  end
294
309
 
295
- def wake_up_executions(exids)
310
+ def wake_up
296
311
 
297
- @mutex.synchronize { @exids.concat(exids).uniq! } if exids.any?
312
+ @wake_up = true
298
313
  end
299
314
 
300
315
  def notify(executor, o)
301
316
 
302
- @hooker.notify(executor, o)
317
+ if executor
318
+ @hooker.notify(executor, o)
319
+ else
320
+ @hooker.wlist.notify(nil, o)
321
+ end
303
322
 
304
323
  rescue => err
305
324
  puts '-sch' * 19
@@ -319,9 +338,9 @@ module Flor
319
338
  #@storage.remove_node(exid, n)
320
339
  # done in Storage#put_execution
321
340
 
322
- @mutex.synchronize do
323
- @timers.reject! { |t| t.exid == exid && t.nid == n['nid'] }
324
- end
341
+ #@mutex.synchronize do
342
+ # @timers.reject! { |t| t.exid == exid && t.nid == n['nid'] }
343
+ #end
325
344
 
326
345
  (@archive[exid] ||= {})[n['nid']] = Flor.dup(n) if @archive
327
346
  end
@@ -341,98 +360,108 @@ module Flor
341
360
 
342
361
  protected
343
362
 
344
- # # return [ domain, tree ]
345
- # #
346
- # def extract_domain_and_tree(s, opts)
347
- #
348
- # if Flor.potential_domain_name?(s)
349
- #
350
- # path = [ opts[:domain], s ].compact.join('.')
351
- # elts = path.split('.')
352
- # flow = @loader.library(path)
353
- #
354
- # fail ArgumentError.new(
355
- # "flow not found at #{path.inspect}"
356
- # ) unless flow
357
- #
358
- # [ elts[0..-2].join('.'), flow ]
359
- #
360
- # else
361
- #
362
- # [ opts[:domain], s ]
363
- # end
364
- # end
365
-
366
- def reload
367
-
368
- now = Time.now
369
-
370
- return if @reloaded_at && (now - @reloaded_at < @reload_frequency)
371
-
372
- @mutex.synchronize do
373
-
374
- @reloaded_at = now
375
- @timers = load_timers
376
- @exids = load_exids
377
- end
363
+ def prepare_on_receive_last(h)
364
+
365
+ ei = h[:exid] || h['exid']
366
+ ni = h[:nid] || h['nid']
367
+ t = h[:tree] || h['tree']
368
+ pl = h[:payload] || h['payload']
369
+
370
+ fail ArgumentError.new('missing :payload to re_apply') unless pl
371
+
372
+ t = Flor::Lang.parse(t, 're_apply', {})
373
+
374
+ [
375
+ { 'point' => 'execute',
376
+ 'exid' => ei, 'nid' => ni,
377
+ 'from' => 'parent',
378
+ 'tree' => t,
379
+ 'payload' => pl }
380
+ ]
378
381
  end
379
382
 
380
- def load_timers
383
+ def prepare_message(point, h)
384
+
385
+ msg = { 'point' => point }
386
+
387
+ [ :exid, :name, :nid, :payload, :on_receive_last ]
388
+ .each { |k| v = h[k] || h[k.to_s]; msg[k.to_s] = v if v }
389
+
390
+ if h[:re_apply]
391
+ msg['on_receive_last'] = prepare_on_receive_last(h)
392
+ end
393
+
394
+ fail ArgumentError.new('missing :exid key') \
395
+ unless msg['exid'].is_a?(String)
396
+ fail ArgumentError.new('missing :name string key') \
397
+ if point == 'signal' && ! msg['name'].is_a?(String)
381
398
 
382
- return [] if @thread_status != :running
383
- @storage.load_timers.sort_by(&:ntime)
399
+ msg
384
400
  end
385
401
 
386
- def load_exids
402
+ def make_idle_message
403
+
404
+ m = {}
405
+ m['point'] = 'idle'
406
+ m['idle_count'] = @idle_count
407
+ m['consumed'] = true
387
408
 
388
- return [] if @thread_status != :running
389
- @storage.load_exids
409
+ m
390
410
  end
391
411
 
392
- def trigger_timers
412
+ def should_wake_up?
393
413
 
394
- now = Time.now.utc
395
- to_re_add = []
414
+ return true if Time.now - @reloaded_at >= @reload_after
396
415
 
397
- loop do
416
+ return true if @wake_up
417
+ return false unless @next_time
398
418
 
399
- timer = @timers.first
400
- break if timer == nil || timer.ntime_t > now
419
+ @next_time <= Flor.tstamp.split('.').first
420
+ end
401
421
 
402
- t = @mutex.synchronize { @timers.shift }
403
- r = @storage.trigger_timer(t)
404
- to_re_add << r if r
405
- end
422
+ def unreserve_messages
406
423
 
407
- if to_re_add.any?
424
+ c = @storage.unreserve_messages(@msg_max_res_time)
408
425
 
409
- @mutex.synchronize do
410
- @timers.concat(to_re_add)
411
- @timers.sort_by! { |t| t.ntime }
412
- end
413
- end
426
+ @logger.info(
427
+ "#{self.class}#unreserve_messages", "#{c} message#{c > 1 ? 's' : ''}"
428
+ ) if c > 0
429
+ end
430
+
431
+ def trigger_timers
432
+
433
+ @storage.trigger_timers
414
434
  end
415
435
 
416
436
  def trigger_executions
417
437
 
418
- return if @exids.empty?
438
+ @executors.select! { |e| e.alive? }
439
+ # drop done executors
419
440
 
420
- exid = nil
441
+ free_executor_count = @max_executors - @executors.size
421
442
 
422
- while exid = @mutex.synchronize { @exids.shift }
443
+ return if free_executor_count < 1
423
444
 
424
- @executors = @executors.select { |e| e.alive? }
425
- # drop done executors
445
+ messages = @storage.load_messages(free_executor_count)
426
446
 
427
- break if @executors.size > @max_executors
428
- next if @executors.find { |e| e.exid == exid }
447
+ messages.each do |exid, ms|
429
448
 
430
- @executors << UnitExecutor.new(self, exid).run
449
+ next unless @storage.reserve_all_messages(ms)
431
450
 
432
- exid = nil
451
+ @idle_count = 0
452
+
453
+ @executors << UnitExecutor.new(self, ms).run
433
454
  end
455
+ end
456
+
457
+ def reload_next_time
458
+
459
+ @next_time = @storage.fetch_next_time
460
+ end
461
+
462
+ def reload_wake_up
434
463
 
435
- @mutex.synchronize { @exids.unshift(exid) } if exid
464
+ @wake_up = @storage.any_message?
436
465
  end
437
466
  end
438
467
  end