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
@@ -57,12 +57,12 @@ module Flor
|
|
57
57
|
|
58
58
|
def self.by_tag(name)
|
59
59
|
|
60
|
-
|
60
|
+
_exids = self.db[:flor_pointers]
|
61
61
|
.where(type: 'tag', name: name, value: nil)
|
62
62
|
.select(:exid)
|
63
63
|
.distinct
|
64
64
|
|
65
|
-
self.where(status: 'active', exid:
|
65
|
+
self.where(status: 'active', exid: _exids)
|
66
66
|
end
|
67
67
|
|
68
68
|
def self.by_var(name, value=:no)
|
@@ -77,12 +77,12 @@ module Flor
|
|
77
77
|
w[:value] = value.to_s
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
_exids = self.db[:flor_pointers]
|
81
81
|
.where(w)
|
82
82
|
.select(:exid)
|
83
83
|
.distinct
|
84
84
|
|
85
|
-
self.where(status: 'active', exid:
|
85
|
+
self.where(status: 'active', exid: _exids)
|
86
86
|
end
|
87
87
|
|
88
88
|
def self.by_tasker(name, taskname=:no)
|
@@ -90,12 +90,12 @@ module Flor
|
|
90
90
|
w = { type: 'tasker', name: name }
|
91
91
|
w[:value] = taskname if taskname != :no
|
92
92
|
|
93
|
-
|
93
|
+
_exids = self.db[:flor_pointers]
|
94
94
|
.where(w)
|
95
95
|
.select(:exid)
|
96
96
|
.distinct
|
97
97
|
|
98
|
-
self.where(status: 'active', exid:
|
98
|
+
self.where(status: 'active', exid: _exids)
|
99
99
|
end
|
100
100
|
|
101
101
|
# def self.by_task(name)
|
data/lib/flor/unit/scheduler.rb
CHANGED
@@ -28,7 +28,9 @@ module Flor
|
|
28
28
|
class Scheduler
|
29
29
|
|
30
30
|
attr_reader :conf, :env
|
31
|
-
|
31
|
+
|
32
|
+
attr_reader :hooker, :storage, :loader, :ganger
|
33
|
+
attr_reader :logger
|
32
34
|
|
33
35
|
attr_reader :thread_status
|
34
36
|
|
@@ -55,10 +57,13 @@ module Flor
|
|
55
57
|
(Flor::Conf.get_class(@conf, 'storage') || Flor::Storage).new(self)
|
56
58
|
@loader =
|
57
59
|
(Flor::Conf.get_class(@conf, 'loader') || Flor::Loader).new(self)
|
58
|
-
@
|
59
|
-
(Flor::Conf.get_class(@conf, '
|
60
|
+
@ganger =
|
61
|
+
(Flor::Conf.get_class(@conf, 'ganger') || Flor::Ganger).new(self)
|
62
|
+
|
63
|
+
@logger =
|
64
|
+
(Flor::Conf.get_class(@conf, 'logger') || Flor::Logger).new(self)
|
60
65
|
|
61
|
-
@hooker.add('logger',
|
66
|
+
@hooker.add('logger', @logger)
|
62
67
|
@hooker.add('wlist', Flor::WaitList)
|
63
68
|
|
64
69
|
@heart_rate = @conf[:sch_heart_rate] || 0.3
|
@@ -89,6 +94,11 @@ module Flor
|
|
89
94
|
@identifier ||= 's' + Digest::MD5.hexdigest(self.object_id.to_s)[0, 5]
|
90
95
|
end
|
91
96
|
|
97
|
+
def has_tasker?(exid, tname)
|
98
|
+
|
99
|
+
@ganger.has_tasker?(exid, tname)
|
100
|
+
end
|
101
|
+
|
92
102
|
def shutdown
|
93
103
|
|
94
104
|
@thread_status = :shutdown
|
@@ -98,7 +108,7 @@ module Flor
|
|
98
108
|
|
99
109
|
@hooker.shutdown
|
100
110
|
@storage.shutdown
|
101
|
-
@
|
111
|
+
@ganger.shutdown
|
102
112
|
end
|
103
113
|
|
104
114
|
def hook(*args, &block)
|
@@ -226,12 +236,12 @@ module Flor
|
|
226
236
|
|
227
237
|
unit = opts[:unit] || @conf['unit'] || 'u0'
|
228
238
|
|
229
|
-
|
239
|
+
@logger.log_src(source, opts)
|
230
240
|
|
231
241
|
exid = Flor.generate_exid(domain, unit)
|
232
242
|
msg = Flor.make_launch_msg(exid, source, opts)
|
233
243
|
|
234
|
-
|
244
|
+
@logger.log_tree(msg['tree'])
|
235
245
|
|
236
246
|
return [ msg, opts ] if opts[:nolaunch]
|
237
247
|
# for testing purposes
|
@@ -316,19 +326,19 @@ module Flor
|
|
316
326
|
(@archive[exid] ||= {})[n['nid']] = Flor.dup(n) if @archive
|
317
327
|
end
|
318
328
|
|
319
|
-
# # Given an exid, returns the execution, if currently executing.
|
320
|
-
# #
|
321
|
-
# def execution(exid)
|
322
|
-
#
|
323
|
-
# ex = @executors.find { |x| x.exid == exid }
|
324
|
-
# ex ? ex.execution : nil
|
325
|
-
# end
|
326
|
-
|
327
329
|
def executor(exid)
|
328
330
|
|
329
331
|
@executors.find { |x| x.exid == exid }
|
330
332
|
end
|
331
333
|
|
334
|
+
# Given an exid, returns the execution, if currently executing.
|
335
|
+
#
|
336
|
+
def execution(exid)
|
337
|
+
|
338
|
+
ex = executor(exid)
|
339
|
+
ex ? ex.execution : nil
|
340
|
+
end
|
341
|
+
|
332
342
|
protected
|
333
343
|
|
334
344
|
# # return [ domain, tree ]
|
data/lib/flor/unit/storage.rb
CHANGED
@@ -72,17 +72,28 @@ module Flor
|
|
72
72
|
db_version == migration_version
|
73
73
|
end
|
74
74
|
|
75
|
-
def synchronize(
|
75
|
+
def synchronize(on=true, &block)
|
76
76
|
|
77
|
-
Thread.current[:sto_errored_items] = nil
|
77
|
+
Thread.current[:sto_errored_items] = nil if on
|
78
78
|
|
79
|
-
if @mutex &&
|
79
|
+
if @mutex && on
|
80
80
|
@mutex.synchronize(&block)
|
81
81
|
else
|
82
82
|
block.call
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
def transync(on=true, &block)
|
87
|
+
|
88
|
+
Thread.current[:sto_errored_items] = nil if on
|
89
|
+
|
90
|
+
if @mutex && on
|
91
|
+
@mutex.synchronize { @db.transaction(&block) }
|
92
|
+
else
|
93
|
+
block.call
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
86
97
|
def migrate(to=nil, from=nil)
|
87
98
|
|
88
99
|
dir =
|
@@ -110,13 +121,16 @@ module Flor
|
|
110
121
|
|
111
122
|
def load_exids
|
112
123
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
124
|
+
synchronize do
|
125
|
+
|
126
|
+
@db[:flor_messages]
|
127
|
+
.select(:exid)
|
128
|
+
.where(status: 'created')
|
129
|
+
.order_by(:ctime)
|
130
|
+
.distinct
|
131
|
+
.all
|
132
|
+
.collect { |r| r[:exid] }
|
133
|
+
end
|
120
134
|
|
121
135
|
rescue => err
|
122
136
|
|
@@ -127,125 +141,125 @@ module Flor
|
|
127
141
|
|
128
142
|
def load_execution(exid)
|
129
143
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
144
|
+
synchronize do
|
145
|
+
|
146
|
+
e = @db[:flor_executions]
|
147
|
+
.select(:id, :content)
|
148
|
+
.where(exid: exid) # status active or terminated doesn't matter
|
149
|
+
.first
|
150
|
+
|
151
|
+
return {
|
152
|
+
'exid' => exid, 'nodes' => {}, 'errors' => [], 'tasks' => {},
|
153
|
+
'counters' => {}, 'start' => Flor.tstamp,
|
154
|
+
'size' => -1
|
155
|
+
} unless e
|
134
156
|
|
135
|
-
if e
|
136
157
|
ex = from_blob(e[:content])
|
158
|
+
|
137
159
|
fail("couldn't parse execution (db id #{e[:id]})") unless ex
|
160
|
+
|
138
161
|
ex['id'] = e[:id]
|
139
162
|
ex['size'] = e[:content].length
|
163
|
+
|
140
164
|
ex
|
141
|
-
else
|
142
|
-
put_execution({
|
143
|
-
'exid' => exid, 'nodes' => {}, 'errors' => [], 'tasks' => {},
|
144
|
-
#'ashes' => {},
|
145
|
-
'counters' => {}, 'start' => Flor.tstamp,
|
146
|
-
'size' => -1
|
147
|
-
})
|
148
165
|
end
|
149
166
|
end
|
150
167
|
|
151
168
|
def put_execution(ex)
|
152
169
|
|
153
|
-
|
170
|
+
status =
|
171
|
+
if ex['nodes']['0'] && ex['nodes']['0']['removed']
|
172
|
+
'terminated'
|
173
|
+
else
|
174
|
+
'active'
|
175
|
+
end
|
154
176
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
else
|
159
|
-
'active'
|
160
|
-
end
|
177
|
+
id = ex['id']
|
178
|
+
|
179
|
+
if id
|
161
180
|
|
162
181
|
ex['end'] ||= Flor.tstamp \
|
163
182
|
if status == 'terminated'
|
164
183
|
ex['duration'] = Time.parse(ex['end']) - Time.parse(ex['start']) \
|
165
184
|
if ex['end']
|
185
|
+
end
|
166
186
|
|
167
|
-
|
168
|
-
|
187
|
+
data = to_blob(ex)
|
188
|
+
ex['size'] = data.length
|
169
189
|
|
170
|
-
|
190
|
+
transync do
|
171
191
|
|
172
|
-
|
192
|
+
now = Flor.tstamp
|
173
193
|
|
174
|
-
|
194
|
+
if id
|
175
195
|
|
196
|
+
@db[:flor_executions]
|
197
|
+
.where(id: id)
|
198
|
+
.update(
|
199
|
+
content: data,
|
200
|
+
status: status,
|
201
|
+
mtime: now)
|
202
|
+
|
203
|
+
else
|
204
|
+
|
205
|
+
ex['id'] =
|
176
206
|
@db[:flor_executions]
|
177
|
-
.
|
178
|
-
|
207
|
+
.insert(
|
208
|
+
domain: Flor.domain(ex['exid']),
|
209
|
+
exid: ex['exid'],
|
179
210
|
content: data,
|
180
|
-
status:
|
211
|
+
status: 'active',
|
212
|
+
ctime: now,
|
181
213
|
mtime: now)
|
182
|
-
|
183
|
-
remove_nodes(ex, status, now)
|
184
|
-
update_pointers(ex, status, now)
|
185
|
-
end
|
186
214
|
end
|
187
|
-
else
|
188
|
-
|
189
|
-
data = to_blob(ex)
|
190
|
-
ex['size'] = data.length
|
191
|
-
|
192
|
-
synchronize do
|
193
|
-
|
194
|
-
@db.transaction do
|
195
215
|
|
196
|
-
|
197
|
-
|
198
|
-
ex['id'] =
|
199
|
-
@db[:flor_executions]
|
200
|
-
.insert(
|
201
|
-
domain: Flor.domain(ex['exid']),
|
202
|
-
exid: ex['exid'],
|
203
|
-
content: data,
|
204
|
-
status: 'active',
|
205
|
-
ctime: now,
|
206
|
-
mtime: now)
|
207
|
-
|
208
|
-
remove_nodes(ex, status, now)
|
209
|
-
update_pointers(ex, status, now)
|
210
|
-
end
|
211
|
-
end
|
216
|
+
remove_nodes(ex, status, now)
|
217
|
+
update_pointers(ex, status, now)
|
212
218
|
end
|
213
219
|
|
214
220
|
ex
|
215
221
|
|
216
222
|
rescue => err
|
223
|
+
|
217
224
|
Thread.current[:sto_errored_items] = [ ex ]
|
218
225
|
raise err
|
219
226
|
end
|
220
227
|
|
221
228
|
def fetch_messages(exid)
|
222
229
|
|
223
|
-
|
224
|
-
@db.transaction do
|
230
|
+
transync do
|
225
231
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
232
|
+
ms = @db[:flor_messages]
|
233
|
+
.select(:id, :content)
|
234
|
+
.where(status: 'created', exid: exid)
|
235
|
+
.order_by(:id)
|
236
|
+
.map { |m| r = from_blob(m[:content]) || {}; r['mid'] = m[:id]; r }
|
231
237
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
238
|
+
@db[:flor_messages]
|
239
|
+
.where(id: ms.collect { |m| m['mid'] })
|
240
|
+
.update(status: 'loaded')
|
241
|
+
#
|
242
|
+
# flag them as "loaded" so that other scheduler don't pick them
|
237
243
|
|
238
|
-
|
239
|
-
end
|
244
|
+
ms
|
240
245
|
end
|
246
|
+
|
247
|
+
rescue => err
|
248
|
+
|
249
|
+
@unit.logger.warn("#{self.class}#fetch_messages()", err, '(returning [])')
|
250
|
+
|
251
|
+
[]
|
241
252
|
end
|
242
253
|
|
243
254
|
def fetch_traps(exid)
|
244
255
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
256
|
+
synchronize do
|
257
|
+
|
258
|
+
traps
|
259
|
+
.where(status: 'active')
|
260
|
+
.where(domain: split_domain(exid))
|
261
|
+
.all
|
262
|
+
end
|
249
263
|
|
250
264
|
rescue => err
|
251
265
|
|
@@ -257,6 +271,7 @@ module Flor
|
|
257
271
|
def consume(messages)
|
258
272
|
|
259
273
|
synchronize do
|
274
|
+
|
260
275
|
if @archive
|
261
276
|
@db[:flor_messages]
|
262
277
|
.where(id: messages.collect { |m| m['mid'] }.compact)
|
@@ -269,17 +284,21 @@ module Flor
|
|
269
284
|
end
|
270
285
|
|
271
286
|
rescue => err
|
287
|
+
|
272
288
|
Thread.current[:sto_errored_items] = messages
|
273
289
|
raise err
|
274
290
|
end
|
275
291
|
|
276
292
|
def load_timers
|
277
293
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
294
|
+
synchronize do
|
295
|
+
|
296
|
+
timers
|
297
|
+
.select(:id, :content)
|
298
|
+
.where(status: 'active')
|
299
|
+
.order_by(:id)
|
300
|
+
.all
|
301
|
+
end
|
283
302
|
|
284
303
|
rescue => err
|
285
304
|
|
@@ -345,6 +364,7 @@ module Flor
|
|
345
364
|
@unit.timers[id]
|
346
365
|
|
347
366
|
rescue => err
|
367
|
+
|
348
368
|
Thread.current[:sto_errored_items] = [ message ]
|
349
369
|
raise err
|
350
370
|
end
|
@@ -355,44 +375,43 @@ module Flor
|
|
355
375
|
|
356
376
|
r = nil
|
357
377
|
|
358
|
-
|
359
|
-
@db.transaction do
|
378
|
+
transync do
|
360
379
|
|
361
380
|
# TODO: cron/every stop conditions maybe?
|
362
381
|
|
363
|
-
|
364
|
-
|
365
|
-
@db[:flor_timers]
|
366
|
-
.where(id: timer.id)
|
367
|
-
.update(
|
368
|
-
count: timer.count + 1,
|
369
|
-
ntime: compute_next_time(timer.type, timer.schedule),
|
370
|
-
mtime: Flor.tstamp)
|
371
|
-
r = timers[timer.id]
|
382
|
+
if timer.type != 'at' && timer.type != 'in'
|
372
383
|
|
373
|
-
|
384
|
+
@db[:flor_timers]
|
385
|
+
.where(id: timer.id)
|
386
|
+
.update(
|
387
|
+
count: timer.count + 1,
|
388
|
+
ntime: compute_next_time(timer.type, timer.schedule),
|
389
|
+
mtime: Flor.tstamp)
|
390
|
+
r = timers[timer.id]
|
374
391
|
|
375
|
-
|
376
|
-
.where(id: timer.id)
|
377
|
-
.update(
|
378
|
-
count: timer.count + 1,
|
379
|
-
status: 'triggered',
|
380
|
-
mtime: Flor.tstamp)
|
392
|
+
elsif @archive
|
381
393
|
|
382
|
-
|
394
|
+
@db[:flor_timers]
|
395
|
+
.where(id: timer.id)
|
396
|
+
.update(
|
397
|
+
count: timer.count + 1,
|
398
|
+
status: 'triggered',
|
399
|
+
mtime: Flor.tstamp)
|
383
400
|
|
384
|
-
|
385
|
-
.where(id: timer.id)
|
386
|
-
.delete
|
387
|
-
end
|
401
|
+
else
|
388
402
|
|
389
|
-
|
403
|
+
@db[:flor_timers]
|
404
|
+
.where(id: timer.id)
|
405
|
+
.delete
|
390
406
|
end
|
407
|
+
|
408
|
+
put_messages([ timer.to_trigger_message ], false)
|
391
409
|
end
|
392
410
|
|
393
411
|
r
|
394
412
|
|
395
413
|
rescue => err
|
414
|
+
|
396
415
|
Thread.current[:sto_errored_items] = [ timer ]
|
397
416
|
raise err
|
398
417
|
end
|
@@ -404,29 +423,28 @@ module Flor
|
|
404
423
|
now = Flor.tstamp
|
405
424
|
|
406
425
|
id =
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
mtime: now)
|
424
|
-
end
|
426
|
+
transync do
|
427
|
+
|
428
|
+
@db[:flor_traps].insert(
|
429
|
+
domain: dom,
|
430
|
+
exid: exid,
|
431
|
+
nid: tra['bnid'],
|
432
|
+
onid: node['nid'],
|
433
|
+
trange: tra['range'],
|
434
|
+
tpoints: tra['points'],
|
435
|
+
ttags: tra['tags'],
|
436
|
+
theats: tra['heats'],
|
437
|
+
theaps: tra['heaps'],
|
438
|
+
content: to_blob(tra),
|
439
|
+
status: 'active',
|
440
|
+
ctime: now,
|
441
|
+
mtime: now)
|
425
442
|
end
|
426
443
|
|
427
444
|
traps[id]
|
428
445
|
|
429
446
|
rescue => err
|
447
|
+
|
430
448
|
Thread.current[:sto_errored_items] = [ node, tra ]
|
431
449
|
raise err
|
432
450
|
end
|