flor 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.tasker.has_tasker?(@executor.exid, key)
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
@@ -38,7 +38,8 @@ require 'flor/unit/waiter'
38
38
  require 'flor/unit/scheduler'
39
39
  require 'flor/unit/models'
40
40
  require 'flor/unit/loader'
41
- require 'flor/unit/tasker'
41
+ require 'flor/unit/ganger'
42
+ require 'flor/unit/taskers'
42
43
 
43
44
  Flor.load_procedures('punit')
44
45
 
@@ -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
- log_run_start if @unit.conf['log_run']
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) if @unit.conf['log_run']
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 Tasker
27
+ class Ganger
28
28
 
29
- # NB: tasker configuration entries start with "tsk_"
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
- tasker = k.new(self, tconf)
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 message['point'] == 'detask'
122
- tasker.cancel(message)
123
- else
124
- tasker.task(message)
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
@@ -32,17 +32,7 @@ module Flor
32
32
 
33
33
  @unit = unit
34
34
 
35
- @dir = @unit.conf['log_dir'] || 'tmp'
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
- @file.close if @file
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
- @mutex.synchronize do
83
- if err
84
- sts = ' ' * stp.length
85
- lvs = ' ' * (@uni.length + 1 + lvl.length)
86
- dig = lvl[0, 1] + Digest::MD5.hexdigest(line)[0, 4]
87
- out.puts("#{stp} #{@uni} #{lvl} #{dig} #{txt}")
88
- err.backtrace.each { |lin| out.puts("#{sts} #{lvs} #{dig} #{lin}") }
89
- else
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
- protected
115
+ def log_run_start(executor)
133
116
 
134
- def prepare_file(t)
117
+ return unless @unit.conf['log_run']
135
118
 
136
- @mutex.synchronize do
119
+ execution = executor.execution
120
+ _c = Flor.colours(out: @out)
121
+ s = StringIO.new
137
122
 
138
- fn = File.join(
139
- @dir,
140
- "#{@unit.conf['env']}_#{t.strftime('%Y-%m-%d')}.log")
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
- if fn != @fname
143
- @file.close if @file
144
- @file = nil
145
- @fname = fn
146
- end
136
+ @out.puts(s.string)
137
+ end
147
138
 
148
- @file ||= File.open(@fname, 'ab')
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