flor 1.0.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -1
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/lib/flor.rb +2 -1
- data/lib/flor/core/texecutor.rb +26 -1
- data/lib/flor/flor.rb +28 -11
- data/lib/flor/id.rb +4 -1
- data/lib/flor/log.rb +12 -7
- data/lib/flor/punit/c_iterator.rb +1 -1
- data/lib/flor/punit/concurrence.rb +6 -5
- data/lib/flor/punit/{m_ram.rb → m_receive_and_merge.rb} +4 -4
- data/lib/flor/tools/firb.rb +33 -0
- data/lib/flor/tools/shell.rb +12 -3
- data/lib/flor/unit.rb +1 -0
- data/lib/flor/unit/caller.rb +6 -4
- data/lib/flor/unit/caller_jruby.rb +8 -7
- data/lib/flor/unit/executor.rb +18 -13
- data/lib/flor/unit/ganger.rb +3 -0
- data/lib/flor/unit/gangers.rb +125 -0
- data/lib/flor/unit/loader.rb +42 -10
- data/lib/flor/unit/logger.rb +11 -2
- data/lib/flor/unit/models/message.rb +5 -0
- data/lib/flor/unit/models/pointer.rb +20 -1
- data/lib/flor/unit/scheduler.rb +16 -8
- data/lib/flor/unit/storage.rb +54 -46
- data/lib/flor/unit/taskers.rb +68 -0
- data/lib/flor/unit/waiter.rb +20 -16
- data/lib/flor/unit/wlist.rb +9 -0
- metadata +5 -3
data/lib/flor/unit/executor.rb
CHANGED
@@ -109,15 +109,13 @@ module Flor
|
|
109
109
|
rescue Exception => exc
|
110
110
|
|
111
111
|
# TODO eventually, have a dump dir
|
112
|
+
|
112
113
|
fn =
|
113
|
-
[
|
114
|
-
'
|
115
|
-
@unit.conf['env'], @unit.identifier, @exid,
|
116
|
-
'r' + counter('runs').to_s
|
117
|
-
].collect(&:to_s).join('_') + '.dump'
|
114
|
+
[ 'flor', @unit.conf['env'], @unit.identifier, @exid,
|
115
|
+
'r' + counter('runs').to_s ].collect(&:to_s).join('_') + '.dump'
|
118
116
|
|
119
117
|
@unit.logger.error(
|
120
|
-
"#{self.class}#do_run()", exc, "(dumping to #{fn})")
|
118
|
+
"#{self.class}#do_run()", exc, "(dumping to #{fn} ...)")
|
121
119
|
|
122
120
|
File.open(fn, 'wb') do |f|
|
123
121
|
f.puts(Flor.to_pretty_s({
|
@@ -134,19 +132,26 @@ module Flor
|
|
134
132
|
f.puts(on_do_run_exc(exc))
|
135
133
|
end
|
136
134
|
|
135
|
+
@unit.logger.error(
|
136
|
+
"#{self.class}#do_run()", exc, "(dumped to #{fn})")
|
137
|
+
|
137
138
|
#puts on_do_run_exc(exc)
|
138
139
|
# dump notification above
|
139
140
|
end
|
140
141
|
|
141
142
|
def task(message)
|
142
143
|
|
143
|
-
|
144
|
-
|
145
|
-
message
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
144
|
+
if message['routed'] == false
|
145
|
+
|
146
|
+
t = message['tasker']
|
147
|
+
n = node(message['nid'])
|
148
|
+
|
149
|
+
msg = n['heat0'] != t ?
|
150
|
+
"tasker #{t.inspect} not found" :
|
151
|
+
"don't know how to apply #{t.inspect}"
|
152
|
+
|
153
|
+
return error_reply(n, message, msg)
|
154
|
+
end
|
150
155
|
|
151
156
|
@unit.ganger.task(self, message)
|
152
157
|
end
|
data/lib/flor/unit/ganger.rb
CHANGED
@@ -54,6 +54,9 @@ module Flor
|
|
54
54
|
(@unit.loader.tasker(domain, 'ganger', message) ||
|
55
55
|
@unit.loader.tasker(domain, 'tasker', message))) ||
|
56
56
|
@unit.loader.tasker(domain, tname, message)
|
57
|
+
#puts "=" * 80
|
58
|
+
#pp tconf
|
59
|
+
#puts "=" * 80
|
57
60
|
|
58
61
|
fail ArgumentError.new(
|
59
62
|
"tasker #{tname.inspect} not found"
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flor
|
4
|
+
|
5
|
+
# A ModuleGanger accepts a `module:` conf entry that points to a Ruby
|
6
|
+
# module. The tasker implementations are searched for among the classes
|
7
|
+
# in the given module.
|
8
|
+
#
|
9
|
+
# Among the tasker classes (classes that respond to on_task, on_detask, ...)
|
10
|
+
# it selects the first tasker that matches the tasker name.
|
11
|
+
#
|
12
|
+
class ModuleGanger
|
13
|
+
|
14
|
+
def initialize(service, conf, message)
|
15
|
+
|
16
|
+
@service = service
|
17
|
+
@conf = conf
|
18
|
+
@message = message
|
19
|
+
end
|
20
|
+
|
21
|
+
def task
|
22
|
+
|
23
|
+
tas = @message['tasker']
|
24
|
+
clas = list_tasker_classes
|
25
|
+
cla = clas.find { |c| tasker_name(c) == tas }
|
26
|
+
|
27
|
+
return [ Flor.dup_and_merge(@message, 'routed' => false) ] \
|
28
|
+
unless cla
|
29
|
+
|
30
|
+
call_tasker(cla)
|
31
|
+
end
|
32
|
+
|
33
|
+
alias detask task
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def list_tasker_classes
|
38
|
+
|
39
|
+
mod_name = @conf['module']
|
40
|
+
|
41
|
+
fail ArgumentError.new('ganger module: configuration entry missing') \
|
42
|
+
unless mod_name
|
43
|
+
|
44
|
+
mod = Flor.const_lookup(mod_name) rescue nil
|
45
|
+
|
46
|
+
fail ArgumentError.new("ganger cannot find module #{mod_name.inspect}") \
|
47
|
+
unless mod
|
48
|
+
|
49
|
+
list_classes(mod, [])
|
50
|
+
end
|
51
|
+
|
52
|
+
def list_classes(start, r)
|
53
|
+
|
54
|
+
# place leave classes on top if possible
|
55
|
+
# within a level, sort alphabetically
|
56
|
+
|
57
|
+
clas = start.constants.collect { |co| start.const_get(co) }
|
58
|
+
clas, mods = clas.partition { |c| c.is_a?(Class) }
|
59
|
+
|
60
|
+
mods.each { |m| list_classes(m, r) }
|
61
|
+
r.concat(clas.select { |c| tasker?(c) }.sort_by { |c| c.name })
|
62
|
+
|
63
|
+
r
|
64
|
+
end
|
65
|
+
|
66
|
+
TASKER_METHODS = [
|
67
|
+
:on, :on_message,
|
68
|
+
:task, :on_task,
|
69
|
+
:detask, :on_detask, :cancel, :on_cancel
|
70
|
+
].freeze
|
71
|
+
|
72
|
+
def tasker?(cla)
|
73
|
+
|
74
|
+
return true if (TASKER_METHODS & cla.public_instance_methods).any?
|
75
|
+
return true if (TASKER_METHODS & cla.public_methods).any?
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
def tasker_name(cla)
|
80
|
+
|
81
|
+
if cla.public_instance_methods.include?(:tasker_name)
|
82
|
+
|
83
|
+
unless cla.respond_to?(:_ganged)
|
84
|
+
class << cla
|
85
|
+
attr_accessor :_ganged
|
86
|
+
end
|
87
|
+
cla._ganged = cla.allocate
|
88
|
+
end
|
89
|
+
|
90
|
+
call_tasker_name(cla._ganged)
|
91
|
+
|
92
|
+
elsif cla.public_methods.include?(:tasker_name)
|
93
|
+
|
94
|
+
call_tasker_name(cla)
|
95
|
+
|
96
|
+
else
|
97
|
+
|
98
|
+
cla.name.split('::').last.gsub(/Tasker\z/, '')
|
99
|
+
.gsub(/([a-z])([A-Z])/) { |_| $1 + '_' + $2.downcase }
|
100
|
+
.gsub(/([A-Z])/) { |c| c.downcase }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def call_tasker_name(o)
|
105
|
+
|
106
|
+
case i = o.method(:tasker_name).arity
|
107
|
+
when 1 then o.tasker_name(@message)
|
108
|
+
when 2 then o.tasker_name(@conf, @message)
|
109
|
+
when 3 then o.tasker_name(@service, @conf, @message)
|
110
|
+
when -1 then o.tasker_name(
|
111
|
+
service: @service, conf: @conf, message: @message)
|
112
|
+
else o.tasker_name
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def call_tasker(c)
|
117
|
+
|
118
|
+
cnf = @conf.merge('class' => c)
|
119
|
+
|
120
|
+
@service.unit.caller
|
121
|
+
.call(@service, cnf, @message)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
data/lib/flor/unit/loader.rb
CHANGED
@@ -46,7 +46,7 @@ module Flor
|
|
46
46
|
.collect { |pa| [ pa, expose_d(pa, {}) ] }
|
47
47
|
.select { |pa, d| Flor.sub_domain?(d, domain) }
|
48
48
|
.sort_by { |pa, d| d.count('.') }
|
49
|
-
.inject({}) { |vars, (pa, _)| vars.merge!(
|
49
|
+
.inject({}) { |vars, (pa, _)| vars.merge!(eval_variables(pa, {})) }
|
50
50
|
end
|
51
51
|
|
52
52
|
#def procedures(path)
|
@@ -87,25 +87,28 @@ module Flor
|
|
87
87
|
.select { |pa| pa.index('/lib/taskers/') }
|
88
88
|
.collect { |pa| [ pa, *expose_dn(pa, {}) ] }
|
89
89
|
.select { |pa, d, n|
|
90
|
-
Flor.sub_domain?([ d, n ]
|
90
|
+
Flor.sub_domain?([ d, n ], domain) ||
|
91
91
|
(n == name && Flor.sub_domain?(d, domain)) }
|
92
92
|
.sort_by { |pa, d, n| d.count('.') }
|
93
93
|
.last
|
94
94
|
|
95
95
|
return nil unless pat
|
96
96
|
|
97
|
-
conf =
|
97
|
+
conf = eval_tasker_conf(pat, message)
|
98
98
|
|
99
99
|
return conf if nam == name
|
100
100
|
|
101
|
-
|
101
|
+
cnf = conf[name]
|
102
102
|
|
103
|
-
return nil unless
|
103
|
+
return nil unless cnf
|
104
104
|
|
105
|
-
|
106
|
-
|
105
|
+
extras = conf.select { |_, v| ! v.is_a?(Hash) }
|
106
|
+
extras['_path'] = pat
|
107
107
|
|
108
|
-
|
108
|
+
(cnf.is_a?(Array) ? cnf : [ cnf ])
|
109
|
+
.each { |h| h.merge!(extras) }
|
110
|
+
|
111
|
+
cnf
|
109
112
|
end
|
110
113
|
|
111
114
|
def hooks(domain)
|
@@ -119,8 +122,8 @@ module Flor
|
|
119
122
|
.select { |pa, d| Flor.sub_domain?(d, domain) }
|
120
123
|
.sort_by { |pa, d| d.count('.') }
|
121
124
|
.collect { |pa, d|
|
122
|
-
|
123
|
-
.each_with_index { |h, i| h['_path'] = pa
|
125
|
+
eval_hook_conf(pa, {})
|
126
|
+
.each_with_index { |h, i| h['_path'] = "#{pa}:#{i}" } }
|
124
127
|
.flatten(1)
|
125
128
|
end
|
126
129
|
|
@@ -247,6 +250,35 @@ module Flor
|
|
247
250
|
end
|
248
251
|
end
|
249
252
|
|
253
|
+
def eval_variables(path, context)
|
254
|
+
eval(path, context)
|
255
|
+
end
|
256
|
+
def eval_tasker_conf(path, context)
|
257
|
+
eval(path, context)
|
258
|
+
end
|
259
|
+
# TODO like in eval_hook_conf, reject fautly tasker confs...
|
260
|
+
# TODO like in eval_hook_conf, reject fautly variables...
|
261
|
+
|
262
|
+
def eval_hook_conf(path, context)
|
263
|
+
|
264
|
+
a = eval(path, context)
|
265
|
+
|
266
|
+
fail ArgumentError.new(
|
267
|
+
"hook conf at #{path} must be an array of hashes"
|
268
|
+
) unless a.is_a?(Array)
|
269
|
+
|
270
|
+
a.each do |e|
|
271
|
+
fail ArgumentError.new(
|
272
|
+
"hook conf at #{path} has non-hash entry #{e.inspect}"
|
273
|
+
) unless e.is_a?(Hash)
|
274
|
+
fail ArgumentError.new(
|
275
|
+
"hook conf at #{path} has incorrect point #{e['point'].inspect}"
|
276
|
+
) unless e['point'].is_a?(String)
|
277
|
+
end
|
278
|
+
|
279
|
+
a
|
280
|
+
end
|
281
|
+
|
250
282
|
def eval(path, context)
|
251
283
|
|
252
284
|
ext =
|
data/lib/flor/unit/logger.rb
CHANGED
@@ -71,7 +71,8 @@ module Flor
|
|
71
71
|
dbi = ' ' + dbi if dbi.length > 0
|
72
72
|
|
73
73
|
txt = elts.collect(&:to_s).join(' ')
|
74
|
-
|
74
|
+
|
75
|
+
err = find_err(elts)
|
75
76
|
|
76
77
|
head = "#{stp} #{@uni}#{dbi} #{lvl} "
|
77
78
|
|
@@ -198,7 +199,8 @@ module Flor
|
|
198
199
|
|
199
200
|
return unless @unit.conf['log_err']
|
200
201
|
|
201
|
-
|
202
|
+
s = Flor.msg_to_detail_s(executor, message, opts.merge(flag: true))
|
203
|
+
@out.puts(s) if s
|
202
204
|
end
|
203
205
|
|
204
206
|
def log_src(source, opts, log_opts={})
|
@@ -245,6 +247,13 @@ module Flor
|
|
245
247
|
message[0..k + 2 + 4] + "(...len#{i - (k + 2 + 1)})" + message[i..-1]
|
246
248
|
end
|
247
249
|
|
250
|
+
def find_err(elts)
|
251
|
+
|
252
|
+
elts.find { |e| e.is_a?(Exception) } ||
|
253
|
+
(defined?(Java) &&
|
254
|
+
elts.find { |e| e.class.ancestors.include?(Java::JavaLang::Error) })
|
255
|
+
end
|
256
|
+
|
248
257
|
class Out
|
249
258
|
|
250
259
|
attr_reader :unit
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
|
3
4
|
module Flor
|
4
5
|
|
5
6
|
class Message < FlorModel
|
@@ -19,6 +20,10 @@ module Flor
|
|
19
20
|
#
|
20
21
|
# index :exid
|
21
22
|
#end
|
23
|
+
|
24
|
+
def nid; data['nid']; end
|
25
|
+
def tasker; data['tasker']; end
|
26
|
+
alias payload data
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
@@ -30,7 +30,7 @@ module Flor
|
|
30
30
|
#end
|
31
31
|
|
32
32
|
# If the pointer is a "var" pointer, returns the full value
|
33
|
-
# for the variable, as
|
33
|
+
# for the variable, as found in the execution's node "0".
|
34
34
|
#
|
35
35
|
def full_value
|
36
36
|
|
@@ -38,6 +38,25 @@ module Flor
|
|
38
38
|
|
39
39
|
node['vars'][name]
|
40
40
|
end
|
41
|
+
|
42
|
+
def attd
|
43
|
+
|
44
|
+
data['atts'].inject({}) { |h, (k, v)| h[k] = v if k; h }
|
45
|
+
|
46
|
+
rescue; []
|
47
|
+
end
|
48
|
+
|
49
|
+
def attl
|
50
|
+
|
51
|
+
data['atts'].inject([]) { |a, (k, v)| a << v if k == nil; a }
|
52
|
+
|
53
|
+
rescue; []
|
54
|
+
end
|
55
|
+
|
56
|
+
def att_texts
|
57
|
+
|
58
|
+
attl.select { |e| e.is_a?(String) }
|
59
|
+
end
|
41
60
|
end
|
42
61
|
end
|
43
62
|
|
data/lib/flor/unit/scheduler.rb
CHANGED
@@ -138,11 +138,7 @@ module Flor
|
|
138
138
|
|
139
139
|
# TODO heartbeat, every x minutes, when idle, log something
|
140
140
|
|
141
|
-
|
142
|
-
"database not ready, " +
|
143
|
-
"db ver: #{@storage.db_version.inspect}, " +
|
144
|
-
"mig ver: #{@storage.migration_version}"
|
145
|
-
) if !! @conf['sto_migration_check'] && @storage.ready?
|
141
|
+
check_migration_version
|
146
142
|
|
147
143
|
@thread_status = :running
|
148
144
|
|
@@ -162,6 +158,15 @@ module Flor
|
|
162
158
|
self
|
163
159
|
end
|
164
160
|
|
161
|
+
def check_migration_version
|
162
|
+
|
163
|
+
fail(
|
164
|
+
"database not ready, " +
|
165
|
+
"db ver: #{@storage.db_version.inspect}, " +
|
166
|
+
"mig ver: #{@storage.migration_version}"
|
167
|
+
) if !! @conf['sto_migration_check'] && @storage.ready?
|
168
|
+
end
|
169
|
+
|
165
170
|
def stop
|
166
171
|
|
167
172
|
@thread_status = :stop
|
@@ -227,6 +232,9 @@ module Flor
|
|
227
232
|
@last_queued_message_id =
|
228
233
|
@storage.put_message(message)
|
229
234
|
|
235
|
+
# Nota bene:
|
236
|
+
# the #wait method is added to the Scheduler by Flor::WaitList
|
237
|
+
|
230
238
|
if opts[:wait]
|
231
239
|
wait(message['exid'], opts)
|
232
240
|
else
|
@@ -587,7 +595,7 @@ module Flor
|
|
587
595
|
|
588
596
|
rescue Exception => ex
|
589
597
|
|
590
|
-
puts
|
598
|
+
puts(on_start_exc(ex))
|
591
599
|
end
|
592
600
|
|
593
601
|
def prepare_message(point, args)
|
@@ -675,9 +683,9 @@ module Flor
|
|
675
683
|
def should_wake_up?
|
676
684
|
|
677
685
|
return true if @wake_up
|
678
|
-
return true if Time.now - @reloaded_at >= reload_after
|
686
|
+
return true if (Time.now - @reloaded_at) >= reload_after
|
679
687
|
|
680
|
-
@next_time && @next_time <= Flor.
|
688
|
+
@next_time && (@next_time <= Flor.tstam)
|
681
689
|
end
|
682
690
|
|
683
691
|
def unreserve_messages
|
data/lib/flor/unit/storage.rb
CHANGED
@@ -7,6 +7,14 @@ module Flor
|
|
7
7
|
|
8
8
|
class Storage
|
9
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
|
+
|
10
18
|
attr_reader :unit, :db, :models
|
11
19
|
|
12
20
|
attr_reader :mutex
|
@@ -352,8 +360,7 @@ module Flor
|
|
352
360
|
|
353
361
|
@db[:flor_messages]
|
354
362
|
.import(
|
355
|
-
|
356
|
-
:status, :ctime, :mtime, :cunit, :munit ],
|
363
|
+
MESSAGE_COLUMNS,
|
357
364
|
unstored.map { |m|
|
358
365
|
[ Flor.domain(m['exid']), m['exid'], m['point'], to_blob(m),
|
359
366
|
'created', n, n, u, u ] }) \
|
@@ -517,25 +524,6 @@ module Flor
|
|
517
524
|
end
|
518
525
|
end
|
519
526
|
|
520
|
-
def put_task_pointer(msg, tname, tconf)
|
521
|
-
|
522
|
-
exid = msg['exid']
|
523
|
-
dom = Flor.domain(exid)
|
524
|
-
|
525
|
-
synchronize do
|
526
|
-
|
527
|
-
@db[:flor_pointers]
|
528
|
-
.insert(
|
529
|
-
domain: dom,
|
530
|
-
exid: exid,
|
531
|
-
nid: msg['nid'],
|
532
|
-
type: 'tasker',
|
533
|
-
name: tname,
|
534
|
-
ctime: Flor.tstamp,
|
535
|
-
cunit: @unit.identifier)
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
527
|
def fetch_next_time
|
540
528
|
|
541
529
|
t =
|
@@ -598,14 +586,13 @@ module Flor
|
|
598
586
|
|
599
587
|
@db[:flor_messages]
|
600
588
|
.where(
|
601
|
-
id: messages.collect { |m| m['mid'] }.compact)
|
589
|
+
id: messages.collect { |m| m['mid'] }.uniq.compact)
|
602
590
|
.update(
|
603
591
|
status: 'consumed', mtime: n, munit: u)
|
604
592
|
|
605
593
|
@db[:flor_messages]
|
606
594
|
.import(
|
607
|
-
|
608
|
-
:status, :ctime, :mtime, :cunit, :munit ],
|
595
|
+
MESSAGE_COLUMNS,
|
609
596
|
messages
|
610
597
|
.select { |m|
|
611
598
|
! m['mid'] && POINTS_TO_ARCHIVE.include?(m['point']) }
|
@@ -621,19 +608,16 @@ module Flor
|
|
621
608
|
|
622
609
|
@db[:flor_messages]
|
623
610
|
.where(
|
624
|
-
id: messages.collect { |m| m['mid'] }.compact)
|
611
|
+
id: messages.collect { |m| m['mid'] }.uniq.compact)
|
625
612
|
.delete
|
626
613
|
end
|
627
614
|
end
|
628
615
|
|
629
616
|
def load_timers
|
630
617
|
|
631
|
-
now = Flor.tstamp
|
632
|
-
no = now[0, now.rindex('.')]
|
633
|
-
|
634
618
|
timers
|
635
619
|
.where(status: 'active')
|
636
|
-
.where { ntime <=
|
620
|
+
.where { ntime <= Flor.tstam }
|
637
621
|
.order(:ntime)
|
638
622
|
.all
|
639
623
|
|
@@ -703,9 +687,9 @@ module Flor
|
|
703
687
|
|
704
688
|
def update_pointers(exe, status, now)
|
705
689
|
|
706
|
-
# Q
|
707
|
-
#
|
708
|
-
#
|
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...
|
709
693
|
|
710
694
|
exid = exe['exid']
|
711
695
|
|
@@ -731,23 +715,25 @@ module Flor
|
|
731
715
|
|
732
716
|
ts = node['tags']
|
733
717
|
ts.each { |t|
|
734
|
-
a << [ dom, exid, nid, 'tag', t, nil, now, u ] } if ts
|
718
|
+
a << [ dom, exid, nid, 'tag', t, nil, now, u, nil ] } if ts
|
735
719
|
|
736
720
|
vs = nid == '0' ? node['vars'] : nil
|
737
721
|
vs.each { |k, v|
|
738
722
|
case v; when Numeric, String, TrueClass, FalseClass, NilClass
|
739
|
-
a << [ dom, exid, '0', 'var', k, v.to_s, now, u ]
|
723
|
+
a << [ dom, exid, '0', 'var', k, v.to_s, now, u, nil ]
|
740
724
|
when Array, Hash
|
741
725
|
s = '(array)'; s = '(object)' if v.is_a?(Hash)
|
742
|
-
a << [ dom, exid, '0', 'var', k, s, now, u ]
|
726
|
+
a << [ dom, exid, '0', 'var', k, s, now, u, nil ]
|
743
727
|
else
|
744
|
-
a << [ dom, exid, '0', 'var', k, nil, now, u ]
|
728
|
+
a << [ dom, exid, '0', 'var', k, nil, now, u, nil ]
|
745
729
|
end } if vs
|
746
730
|
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
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
|
751
737
|
|
752
738
|
a }
|
753
739
|
|
@@ -755,17 +741,35 @@ module Flor
|
|
755
741
|
.where(exid: exid)
|
756
742
|
.select(:nid, :type, :name)
|
757
743
|
.all
|
758
|
-
pointers.reject! { |_, _, ni, ty, na, _, _, _|
|
744
|
+
pointers.reject! { |_, _, ni, ty, na, _, _, _, _|
|
759
745
|
cps.find { |cp| cp[:nid] == ni && cp[:type] == ty && cp[:name] == na } }
|
760
746
|
#
|
761
747
|
# don't insert when already inserted
|
762
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
|
+
|
763
757
|
@db[:flor_pointers]
|
764
758
|
.import(
|
765
|
-
|
759
|
+
pointer_columns,
|
766
760
|
pointers)
|
767
761
|
end
|
768
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
|
+
|
769
773
|
def determine_type_and_schedule(message)
|
770
774
|
|
771
775
|
t, s = message['type'], message['string']
|
@@ -822,8 +826,9 @@ module Flor
|
|
822
826
|
fail ArgumentError.new("no 'sto_uri' conf, cannot connect to db") \
|
823
827
|
unless uri
|
824
828
|
|
825
|
-
|
826
|
-
|
829
|
+
return Kernel.const_get(uri) \
|
830
|
+
if uri.is_a?(String) && uri.match(/\A[A-Z]+\z/)
|
831
|
+
# for cases where uri == 'DB'
|
827
832
|
|
828
833
|
Sequel.connect(uri)
|
829
834
|
end
|
@@ -844,8 +849,11 @@ module Flor
|
|
844
849
|
# NB: -1 means "check at every use"
|
845
850
|
end
|
846
851
|
|
847
|
-
@
|
848
|
-
|
852
|
+
if @unit.conf['sto_db_logger'] != false
|
853
|
+
|
854
|
+
@db_logger = DbLogger.new(@unit)
|
855
|
+
@db.loggers << @db_logger
|
856
|
+
end
|
849
857
|
end
|
850
858
|
|
851
859
|
class << self
|