flor 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|