flor 0.9.2 → 0.9.3
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.
- data/CHANGELOG.md +6 -0
- data/Makefile +4 -0
- data/fail.txt +16 -7
- data/lib/flor.rb +1 -1
- data/lib/flor/colours.rb +43 -92
- data/lib/flor/conf.rb +13 -1
- data/lib/flor/core/executor.rb +4 -3
- data/lib/flor/core/node.rb +1 -1
- data/lib/flor/core/procedure.rb +1 -1
- data/lib/flor/core/texecutor.rb +23 -7
- data/lib/flor/log.rb +34 -26
- data/lib/flor/punit/task.rb +1 -1
- data/lib/flor/unit.rb +2 -1
- data/lib/flor/unit/executor.rb +5 -61
- data/lib/flor/unit/{tasker.rb → ganger.rb} +16 -7
- data/lib/flor/unit/logger.rb +164 -49
- data/lib/flor/unit/models/execution.rb +6 -6
- data/lib/flor/unit/scheduler.rb +25 -15
- data/lib/flor/unit/storage.rb +148 -130
- data/lib/flor/unit/taskers.rb +54 -0
- data/out.txt +206 -0
- metadata +5 -3
data/lib/flor/punit/task.rb
CHANGED
@@ -51,7 +51,7 @@ class Flor::Pro::Task < Flor::Procedure
|
|
51
51
|
# "clean up" assign: 'alan'
|
52
52
|
# alan task: 'clean up'
|
53
53
|
|
54
|
-
#@executor.unit.
|
54
|
+
#@executor.unit.has_tasker?(@executor.exid, key)
|
55
55
|
|
56
56
|
ni = att(nil)
|
57
57
|
ta = att('by', 'for', 'assign')
|
data/lib/flor/unit.rb
CHANGED
data/lib/flor/unit/executor.rb
CHANGED
@@ -28,6 +28,7 @@ module Flor
|
|
28
28
|
class UnitExecutor < Flor::Executor
|
29
29
|
|
30
30
|
attr_reader :exid
|
31
|
+
attr_reader :consumed
|
31
32
|
|
32
33
|
def initialize(unit, exid)
|
33
34
|
|
@@ -66,7 +67,7 @@ module Flor
|
|
66
67
|
|
67
68
|
def do_run
|
68
69
|
|
69
|
-
|
70
|
+
@unit.logger.log_run_start(self)
|
70
71
|
|
71
72
|
counter_next('runs')
|
72
73
|
|
@@ -91,9 +92,6 @@ module Flor
|
|
91
92
|
ms = process(m)
|
92
93
|
|
93
94
|
@consumed << m
|
94
|
-
#
|
95
|
-
#@consumed << m unless ms.include?(m)
|
96
|
-
# TODO what if msg is held / pushed back?
|
97
95
|
|
98
96
|
ims, oms = ms.partition { |m| m['exid'] == @exid }
|
99
97
|
# qui est "in", qui est "out"?
|
@@ -112,7 +110,7 @@ module Flor
|
|
112
110
|
@unit.storage.put_execution(@execution)
|
113
111
|
@unit.storage.put_messages(@messages)
|
114
112
|
|
115
|
-
log_run_end(t0)
|
113
|
+
@unit.logger.log_run_end(self, t0)
|
116
114
|
|
117
115
|
@consumed.clear
|
118
116
|
|
@@ -130,7 +128,6 @@ module Flor
|
|
130
128
|
"#{self.class}#do_run()", exc, "(dumping to #{fn})")
|
131
129
|
|
132
130
|
File.open(fn, 'wb') do |f|
|
133
|
-
#f.puts(JSON.pretty_generate({
|
134
131
|
f.puts(Flor.to_pretty_s({
|
135
132
|
execution: @execution,
|
136
133
|
messages: @messages,
|
@@ -145,7 +142,8 @@ module Flor
|
|
145
142
|
f.puts(on_do_run_exc(exc))
|
146
143
|
end
|
147
144
|
|
148
|
-
puts on_do_run_exc(exc)
|
145
|
+
#puts on_do_run_exc(exc)
|
146
|
+
# dump notification above
|
149
147
|
end
|
150
148
|
|
151
149
|
def schedule(message)
|
@@ -165,60 +163,6 @@ module Flor
|
|
165
163
|
[ m ]
|
166
164
|
end
|
167
165
|
|
168
|
-
def log_run_start
|
169
|
-
|
170
|
-
_c = Flor.colours
|
171
|
-
|
172
|
-
s = StringIO.new
|
173
|
-
|
174
|
-
s << _c.dg
|
175
|
-
s << " /--- #{_c.lg}run starts#{_c.dg} "
|
176
|
-
s << "#{self.class} #{self.object_id} #{@exid}"
|
177
|
-
s << "\n | "
|
178
|
-
s << { thread: Thread.current.object_id }.inspect
|
179
|
-
s << "\n | "
|
180
|
-
s << {
|
181
|
-
counters: @execution['counters'],
|
182
|
-
nodes: @execution['nodes'].size,
|
183
|
-
size: @execution['size']
|
184
|
-
}.inspect
|
185
|
-
s << _c.rs
|
186
|
-
|
187
|
-
puts s.string
|
188
|
-
end
|
189
|
-
|
190
|
-
def log_run_end(t0)
|
191
|
-
|
192
|
-
_c = Flor.colours
|
193
|
-
|
194
|
-
s = StringIO.new
|
195
|
-
|
196
|
-
s << _c.dg
|
197
|
-
s << " | run ends #{self.class} #{self.object_id} #{@exid}"
|
198
|
-
s << "\n | "; s << { took: Time.now - t0 }.inspect
|
199
|
-
s << "\n | "; s << {
|
200
|
-
thread: Thread.current.object_id,
|
201
|
-
consumed: @consumed.size,
|
202
|
-
traps: @traps.size,
|
203
|
-
}.inspect
|
204
|
-
s << "\n | "; s << {
|
205
|
-
#own_traps: @traps.reject { |t| t.texid == nil }.size, # FIXME
|
206
|
-
counters: @execution['counters'],
|
207
|
-
nodes: @execution['nodes'].size,
|
208
|
-
size: @execution['size']
|
209
|
-
}.inspect
|
210
|
-
if @unit.archive
|
211
|
-
s << "\n | "
|
212
|
-
s << {
|
213
|
-
archive_size: @unit.archive[@exid].size
|
214
|
-
}.inspect
|
215
|
-
end
|
216
|
-
s << "\n \\--- ."
|
217
|
-
s << _c.rs
|
218
|
-
|
219
|
-
puts s.string
|
220
|
-
end
|
221
|
-
|
222
166
|
def on_do_run_exc(e)
|
223
167
|
|
224
168
|
io = StringIO.new
|
@@ -24,9 +24,11 @@
|
|
24
24
|
|
25
25
|
module Flor
|
26
26
|
|
27
|
-
class
|
27
|
+
class Ganger
|
28
28
|
|
29
|
-
# NB: tasker configuration entries start with "
|
29
|
+
# NB: tasker configuration entries start with "gan_"
|
30
|
+
|
31
|
+
attr_reader :unit
|
30
32
|
|
31
33
|
def initialize(unit)
|
32
34
|
|
@@ -51,6 +53,8 @@ module Flor
|
|
51
53
|
tconf =
|
52
54
|
( ! message['routed'] && @unit.loader.tasker(domain, 'tasker')) ||
|
53
55
|
@unit.loader.tasker(domain, tname)
|
56
|
+
#
|
57
|
+
# TODO `.tasker(domain, 'ganger')`
|
54
58
|
|
55
59
|
fail ArgumentError.new(
|
56
60
|
"tasker #{tname.inspect} not found"
|
@@ -115,13 +119,18 @@ module Flor
|
|
115
119
|
k = tconf['on_task']['class']
|
116
120
|
k = Flor.const_lookup(k)
|
117
121
|
|
118
|
-
|
122
|
+
ka = k.instance_method(:initialize).arity
|
123
|
+
|
124
|
+
m =
|
125
|
+
message['point'] == 'detask' ?
|
126
|
+
:cancel :
|
127
|
+
:task
|
119
128
|
|
120
129
|
r =
|
121
|
-
if
|
122
|
-
|
123
|
-
else
|
124
|
-
|
130
|
+
if ka == 2
|
131
|
+
k.new(self, tconf).send(m, message)
|
132
|
+
else # ka == 3
|
133
|
+
k.new(self, tconf, message).send(m)
|
125
134
|
end
|
126
135
|
|
127
136
|
# if the tasker returns something intelligible, use it
|
data/lib/flor/unit/logger.rb
CHANGED
@@ -32,17 +32,7 @@ module Flor
|
|
32
32
|
|
33
33
|
@unit = unit
|
34
34
|
|
35
|
-
@
|
36
|
-
@dir = '.' unless @dir.is_a?(String) && File.exist?(@dir)
|
37
|
-
|
38
|
-
@fname = nil
|
39
|
-
@file = nil
|
40
|
-
|
41
|
-
@mutex = Mutex.new
|
42
|
-
|
43
|
-
@unit.singleton_class.instance_eval do
|
44
|
-
define_method(:logger) { @hooker['logger'] }
|
45
|
-
end
|
35
|
+
@out = prepare_out
|
46
36
|
|
47
37
|
@uni = @unit.identifier
|
48
38
|
end
|
@@ -51,7 +41,8 @@ module Flor
|
|
51
41
|
|
52
42
|
def shutdown
|
53
43
|
|
54
|
-
|
44
|
+
#@file.close if @file
|
45
|
+
@out.close
|
55
46
|
end
|
56
47
|
|
57
48
|
def debug(*m); log(:debug, *m); end
|
@@ -61,63 +52,55 @@ module Flor
|
|
61
52
|
|
62
53
|
def log(level, *elts)
|
63
54
|
|
64
|
-
return if [ nil, 'null', false ].include?(@dir)
|
65
|
-
|
66
55
|
n = Time.now.utc
|
67
56
|
stp = Flor.tstamp(n)
|
68
57
|
|
69
|
-
out =
|
70
|
-
case @dir
|
71
|
-
when 'stdout' then $stdout
|
72
|
-
when 'stderr' then $stderr
|
73
|
-
else prepare_file(n)
|
74
|
-
end
|
75
|
-
|
76
58
|
lvl = level.to_s.upcase
|
77
59
|
txt = elts.collect(&:to_s).join(' ')
|
78
60
|
err = elts.find { |e| e.is_a?(Exception) }
|
79
61
|
|
80
62
|
line = "#{stp} #{@uni} #{lvl} #{txt}"
|
81
63
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
out.puts(line)
|
91
|
-
end
|
64
|
+
if err
|
65
|
+
sts = ' ' * stp.length
|
66
|
+
lvs = ' ' * (@uni.length + 1 + lvl.length)
|
67
|
+
dig = lvl[0, 1] + Digest::MD5.hexdigest(line)[0, 4]
|
68
|
+
@out.puts("#{stp} #{@uni} #{lvl} #{dig} #{txt}")
|
69
|
+
err.backtrace.each { |lin| @out.puts(" #{dig} #{@uni} #{lin}") }
|
70
|
+
else
|
71
|
+
@out.puts(line)
|
92
72
|
end
|
93
73
|
end
|
94
74
|
|
95
75
|
def notify(executor, msg)
|
96
76
|
|
77
|
+
# TODO log to outfile
|
97
78
|
if msg['rewritten'] && @unit.conf['log_tree_rw']
|
98
79
|
|
99
80
|
Flor.print_compact_tree(
|
100
81
|
msg['rewritten'], msg['nid'],
|
101
|
-
ind: 6, title: "rewrote #{msg['exid']} #{msg['nid']}"
|
82
|
+
ind: 6, title: "rewrote #{msg['exid']} #{msg['nid']}",
|
83
|
+
out: @out)
|
102
84
|
Flor.print_compact_tree(
|
103
85
|
msg['tree'], msg['nid'],
|
104
86
|
ind: 6, title: "into #{msg['exid']} #{msg['nid']}",
|
105
|
-
close: true
|
87
|
+
close: true,
|
88
|
+
out: @out)
|
106
89
|
end
|
107
90
|
|
108
91
|
if @unit.conf['log_msg']
|
109
92
|
|
110
|
-
Flor.log_message(executor, msg)
|
93
|
+
Flor.log_message(executor, msg, out: @out)
|
111
94
|
end
|
112
95
|
|
113
|
-
[]
|
96
|
+
[] # we're only logging, do not queue further messages
|
114
97
|
end
|
115
98
|
|
116
99
|
def db_log(level, msg)
|
117
100
|
|
118
101
|
return unless @unit.conf['log_sto']
|
119
102
|
|
120
|
-
_c = Flor.colours
|
103
|
+
_c = Flor.colours(out: @out)
|
121
104
|
|
122
105
|
#m = msg.match(/ (INSERT|UPDATE) .+ (0?[xX]'?[a-fA-F0-9]+'?)/)
|
123
106
|
#msg = msg.sub(m[2], "#{m[2][0, 14]}(...len#{m[2].length})") if m
|
@@ -126,29 +109,90 @@ module Flor
|
|
126
109
|
#
|
127
110
|
msg = summarize_blob(msg)
|
128
111
|
|
129
|
-
puts "#{_c.blg}sto#{_c.rs} t#{Thread.current.object_id} #{level.upcase} #{msg}"
|
112
|
+
@out.puts "#{_c.blg}sto#{_c.rs} t#{Thread.current.object_id} #{level.upcase} #{msg}"
|
130
113
|
end
|
131
114
|
|
132
|
-
|
115
|
+
def log_run_start(executor)
|
133
116
|
|
134
|
-
|
117
|
+
return unless @unit.conf['log_run']
|
135
118
|
|
136
|
-
|
119
|
+
execution = executor.execution
|
120
|
+
_c = Flor.colours(out: @out)
|
121
|
+
s = StringIO.new
|
137
122
|
|
138
|
-
|
139
|
-
|
140
|
-
|
123
|
+
s << _c.dg
|
124
|
+
s << " /--- #{_c.lg}run starts#{_c.dg} "
|
125
|
+
s << "#{executor.class} #{executor.object_id} #{execution['exid']}"
|
126
|
+
s << "\n | "
|
127
|
+
s << { thread: Thread.current.object_id }.inspect
|
128
|
+
s << "\n | "
|
129
|
+
s << {
|
130
|
+
counters: execution['counters'],
|
131
|
+
nodes: execution['nodes'].size,
|
132
|
+
size: execution['size']
|
133
|
+
}.inspect
|
134
|
+
s << _c.rs
|
141
135
|
|
142
|
-
|
143
|
-
|
144
|
-
@file = nil
|
145
|
-
@fname = fn
|
146
|
-
end
|
136
|
+
@out.puts(s.string)
|
137
|
+
end
|
147
138
|
|
148
|
-
|
139
|
+
def log_run_end(executor, t0)
|
140
|
+
|
141
|
+
return unless @unit.conf['log_run']
|
142
|
+
|
143
|
+
execution = executor.execution
|
144
|
+
_c = Flor.colours(out: @out)
|
145
|
+
s = StringIO.new
|
146
|
+
|
147
|
+
s << _c.dg
|
148
|
+
s << " | run ends #{self.class} #{self.object_id} #{@exid}"
|
149
|
+
s << "\n | "; s << { took: Time.now - t0 }.inspect
|
150
|
+
s << "\n | "; s << {
|
151
|
+
thread: Thread.current.object_id,
|
152
|
+
consumed: executor.consumed.count,
|
153
|
+
traps: executor.traps.count,
|
154
|
+
}.inspect
|
155
|
+
s << "\n | "; s << {
|
156
|
+
#own_traps: @traps.reject { |t| t.texid == nil }.size, # FIXME
|
157
|
+
counters: execution['counters'],
|
158
|
+
nodes: execution['nodes'].size,
|
159
|
+
size: execution['size']
|
160
|
+
}.inspect
|
161
|
+
if @unit.archive
|
162
|
+
s << "\n | "
|
163
|
+
s << {
|
164
|
+
archive_size: @unit.archive[@exid].size
|
165
|
+
}.inspect
|
149
166
|
end
|
167
|
+
s << "\n \\--- ."
|
168
|
+
s << _c.rs
|
169
|
+
|
170
|
+
@out.puts(s.string)
|
171
|
+
end
|
172
|
+
|
173
|
+
def log_err(executor, message, opts={})
|
174
|
+
|
175
|
+
return unless @unit.conf['log_err']
|
176
|
+
|
177
|
+
Flor.print_detail_msg(executor, message, opts.merge(out: @out))
|
178
|
+
end
|
179
|
+
|
180
|
+
def log_src(source, opts, log_opts={})
|
181
|
+
|
182
|
+
return unless @unit.conf['log_src']
|
183
|
+
|
184
|
+
Flor.print_src(source, opts, log_opts.merge(out: @out))
|
185
|
+
end
|
186
|
+
|
187
|
+
def log_tree(tree, nid='0', opts={})
|
188
|
+
|
189
|
+
return unless @unit.conf['log_tree']
|
190
|
+
|
191
|
+
Flor.print_tree(tree, nid, opts.merge(out: @out))
|
150
192
|
end
|
151
193
|
|
194
|
+
protected
|
195
|
+
|
152
196
|
BLOB_CHARS = (('a'..'f').to_a + ('A'..'F').to_a + ('0'..'9').to_a).freeze
|
153
197
|
|
154
198
|
def summarize_blob(message)
|
@@ -176,6 +220,77 @@ module Flor
|
|
176
220
|
|
177
221
|
message[0..k + 2 + 4] + "(...len#{i - (k + 2 + 1)})" + message[i..-1]
|
178
222
|
end
|
223
|
+
|
224
|
+
def prepare_out
|
225
|
+
|
226
|
+
case (o = @unit.conf['log_out'] || 'stdout')
|
227
|
+
when false, 'null' then NoOut.new(@unit)
|
228
|
+
when true, 'stdout' then StdOut.new(@unit, $stdout)
|
229
|
+
when 'stderr' then StdOut.new(@unit, $stderr)
|
230
|
+
when /::/ then Flor.const_lookup(o).new(@unit)
|
231
|
+
else FileOut.new(@unit, o)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
class Out
|
236
|
+
attr_reader :unit
|
237
|
+
def initialize(unit); @unit = unit; end
|
238
|
+
def log_colours?; @unit.conf.fetch('log_colours') { :no } == true; end
|
239
|
+
def puts(s); end
|
240
|
+
def flush; end
|
241
|
+
def close; end
|
242
|
+
end
|
243
|
+
|
244
|
+
class NoOut < Out
|
245
|
+
def log_colours?; false; end
|
246
|
+
end
|
247
|
+
|
248
|
+
class StdOut < Out
|
249
|
+
def initialize(unit, f); super(unit); @f = f; end
|
250
|
+
def log_colours?
|
251
|
+
lc = @unit.conf.fetch('log_colours') { :no }
|
252
|
+
return lc if [ true, false ].include?(lc)
|
253
|
+
@f.tty?
|
254
|
+
end
|
255
|
+
def puts(s); @f.puts(s); end
|
256
|
+
def flush; @f.flush; end
|
257
|
+
end
|
258
|
+
|
259
|
+
class FileOut < Out
|
260
|
+
|
261
|
+
def initialize(unit, dir)
|
262
|
+
|
263
|
+
super(unit)
|
264
|
+
@dir = dir
|
265
|
+
|
266
|
+
@mutex = Mutex.new
|
267
|
+
@file = nil
|
268
|
+
@fname = nil
|
269
|
+
end
|
270
|
+
|
271
|
+
def flush; @mutex.synchronize { @file.flush if @file }; end
|
272
|
+
def close; @mutex.synchronize { @file.close if @file }; end
|
273
|
+
|
274
|
+
def puts(s)
|
275
|
+
@mutex.synchronize { prepare_file.puts(s) }
|
276
|
+
end # TODO tstamp!
|
277
|
+
|
278
|
+
protected
|
279
|
+
|
280
|
+
def prepare_file
|
281
|
+
|
282
|
+
fn = File.join(
|
283
|
+
@dir, "#{@unit.env}_#{Time.now.strftime('%Y-%m-%d')}.log")
|
284
|
+
|
285
|
+
if fn != @fname
|
286
|
+
@file.close if @file
|
287
|
+
@file = nil
|
288
|
+
@fname = fn
|
289
|
+
end
|
290
|
+
|
291
|
+
@file ||= File.open(@fname, 'ab')
|
292
|
+
end
|
293
|
+
end
|
179
294
|
end
|
180
295
|
end
|
181
296
|
|