pampa 2.0.12 → 2.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pampa.rb +177 -34
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0137672f5c0b7c0cd2be75ddf221d84d65d824c8ba4bdf87b5cfd369bf9eef14
|
4
|
+
data.tar.gz: 7d8bb53cfd11c3d37b69b8408c544f1718fc0178f130f5f16785771e84af9ac9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz: '
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '00540329934fd5d5d22cae40967fee37ba4eba39a4383d324999da4902ea0a8e83c489a320820102ec3c8175a37fdace4a2147b0be490ec22e6c8380ab29f1a2'
|
7
|
+
data.tar.gz: 4efb7d405e0aa5d6a7c6f8b613b83fe14511d2f15a14f9338c48da4676204631a0c99fc34491474571c164779ad730e5820b397f2dc93a3abb3ff5bee6ec1851
|
data/lib/pampa.rb
CHANGED
@@ -9,6 +9,11 @@ module BlackStack
|
|
9
9
|
module Pampa
|
10
10
|
# activate this flag if you want to add pampa nodes to blackstack-deployer.
|
11
11
|
@@integrate_with_blackstack_deployer = false
|
12
|
+
# setup custom locations for config and worker files.
|
13
|
+
@@config_filename = "config.rb"
|
14
|
+
@@worker_filename = "worker.rb"
|
15
|
+
# setu the directory where the worker.rb file will be lauched, and the log files will be stored.
|
16
|
+
@@working_directory = "$HOME/pampa"
|
12
17
|
# arrays of workers, nodes, and jobs.
|
13
18
|
@@nodes = []
|
14
19
|
@@jobs = []
|
@@ -17,7 +22,43 @@ module BlackStack
|
|
17
22
|
@@logger = BlackStack::DummyLogger.new(nil)
|
18
23
|
# Connection string to the database. Example: mysql2://user:password@localhost:3306/database
|
19
24
|
@@connection_string = nil
|
20
|
-
|
25
|
+
|
26
|
+
# @@integrate_with_blackstack_deployer
|
27
|
+
def self.integrate_with_blackstack_deployer()
|
28
|
+
@@integrate_with_blackstack_deployer
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.set_integrate_with_blackstack_deployer(b)
|
32
|
+
@@integrate_with_blackstack_deployer = b
|
33
|
+
end
|
34
|
+
|
35
|
+
# @@config_filename
|
36
|
+
def self.config_filename()
|
37
|
+
@@config_filename
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.set_config_filename(s)
|
41
|
+
@@config_filename = s
|
42
|
+
end
|
43
|
+
|
44
|
+
# @@worker_filename
|
45
|
+
def self.worker_filename()
|
46
|
+
@@worker_filename
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.set_worker_filename(s)
|
50
|
+
@@worker_filename = s
|
51
|
+
end
|
52
|
+
|
53
|
+
## @@working_directory
|
54
|
+
def self.working_directory()
|
55
|
+
@@working_directory
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.set_working_directory(s)
|
59
|
+
@@working_directory = s
|
60
|
+
end
|
61
|
+
|
21
62
|
# define a filename for the log file.
|
22
63
|
def self.set_log_filename(s)
|
23
64
|
@@log_filename = s
|
@@ -33,15 +74,6 @@ module BlackStack
|
|
33
74
|
@@logger = l
|
34
75
|
end
|
35
76
|
|
36
|
-
# @@integrate_with_blackstack_deployer
|
37
|
-
def self.integrate_with_blackstack_deployer()
|
38
|
-
@@integrate_with_blackstack_deployer
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.set_integrate_with_blackstack_deployer(b)
|
42
|
-
@@integrate_with_blackstack_deployer = b
|
43
|
-
end
|
44
|
-
|
45
77
|
# return the log filename.
|
46
78
|
def self.log_filename()
|
47
79
|
@@log_filename
|
@@ -297,10 +329,10 @@ module BlackStack
|
|
297
329
|
|
298
330
|
# connect the nodes via ssh.
|
299
331
|
# kill all Ruby processes except this one.
|
300
|
-
# rename any existing folder
|
301
|
-
# create a new folder
|
302
|
-
# build the file
|
303
|
-
# copy the file
|
332
|
+
# rename any existing folder $HOME/pampa to $HOME/pampa.<current timestamp>.
|
333
|
+
# create a new folder $HOME/pampa.
|
334
|
+
# build the file $HOME/pampa/config.rb in the remote node.
|
335
|
+
# copy the file $HOME/pampa/worker.rb to the remote node.
|
304
336
|
# run the number of workers specified in the configuration of the Pampa module.
|
305
337
|
# return an array with the IDs of the workers.
|
306
338
|
#
|
@@ -308,7 +340,7 @@ module BlackStack
|
|
308
340
|
# - config: relative path of the configuration file. Example: '../config.rb'
|
309
341
|
# - worker: relative path of the worker.rb file. Example: '../worker.rb'
|
310
342
|
#
|
311
|
-
def self.deploy(
|
343
|
+
def self.deploy()
|
312
344
|
# validate: the connection string is not nil
|
313
345
|
raise "The connection string is nil" if @@connection_string.nil?
|
314
346
|
# validate: the connection string is not empty
|
@@ -326,33 +358,33 @@ module BlackStack
|
|
326
358
|
l.done
|
327
359
|
# kill all ruby processes except this one
|
328
360
|
l.logs("Killing all Ruby processes except this one... ")
|
329
|
-
|
361
|
+
node.exec("ps ax | grep ruby | grep -v grep | grep -v #{Process.pid} | cut -b3-7 | xargs -t kill;", false);
|
330
362
|
l.done
|
331
363
|
# rename any existing folder ~/code/pampa to ~/code/pampa.<current timestamp>.
|
332
364
|
l.logs("Renaming old folder... ")
|
333
|
-
|
365
|
+
node.exec("mv #{BlackStack::Pampa.working_directory} #{BlackStack::Pampa.working_directory}.#{Time.now().to_i.to_s}", false);
|
334
366
|
l.done
|
335
367
|
# create a new folder ~/code. - ignore if it already exists.
|
336
368
|
l.logs("Creating new folder... ")
|
337
|
-
|
369
|
+
node.exec("mkdir #{BlackStack::Pampa.working_directory}", false);
|
338
370
|
l.done
|
339
|
-
# build the file
|
371
|
+
# build the file $HOME/pampa/config.rb in the remote node. - Be sure the BlackStack::Pampa.to_hash.to_s don't have single-quotes (') in the string.
|
340
372
|
l.logs("Building config file... ")
|
341
|
-
s = "echo \"#{File.read(config_filename)}\" >
|
342
|
-
|
373
|
+
s = "echo \"#{File.read(config_filename)}\" > #{BlackStack::Pampa.working_directory}/#{BlackStack::Pampa.config_filename}"
|
374
|
+
node.exec("#{s}", false);
|
343
375
|
l.done
|
344
|
-
# copy the file
|
376
|
+
# copy the file $HOME/pampa/worker.rb to the remote node. - Be sure the script don't have single-quotes (') in the string.
|
345
377
|
l.logs("Copying worker file... ")
|
346
|
-
s = "echo \"#{File.read(worker_filename)}\" >
|
347
|
-
|
378
|
+
s = "echo \"#{File.read(worker_filename)}\" > #{BlackStack::Pampa.working_directory}/#{BlackStack::Pampa.worker_filename}"
|
379
|
+
node.exec("#{s}", false);
|
348
380
|
l.done
|
349
381
|
# run the number of workers specified in the configuration of the Pampa module.
|
350
382
|
node.workers.each { |worker|
|
351
383
|
# run the worker
|
352
384
|
# add these parameters for debug: debug=yes pampa=~/code/pampa/lib/pampa.rb
|
353
385
|
l.logs "Running worker #{worker.id}... "
|
354
|
-
s = "nohup ruby
|
355
|
-
|
386
|
+
s = "nohup ruby #{BlackStack::Pampa.worker_filename} id=#{worker.id} config=#{BlackStack::Pampa.working_directory}/#{BlackStack::Pampa.config_filename} >/dev/null 2>&1 &"
|
387
|
+
node.exec("#{s}", false);
|
356
388
|
l.done
|
357
389
|
}
|
358
390
|
# disconnect the node
|
@@ -368,7 +400,7 @@ module BlackStack
|
|
368
400
|
# run the number of workers specified in the configuration of the Pampa module.
|
369
401
|
# return an array with the IDs of the workers.
|
370
402
|
#
|
371
|
-
def self.start(
|
403
|
+
def self.start()
|
372
404
|
# validate: the connection string is not nil
|
373
405
|
raise "The connection string is nil" if @@connection_string.nil?
|
374
406
|
# validate: the connection string is not empty
|
@@ -386,15 +418,23 @@ module BlackStack
|
|
386
418
|
l.done
|
387
419
|
# kill all ruby processes except this one
|
388
420
|
l.logs("Killing all Ruby processes except this one... ")
|
389
|
-
|
421
|
+
node.exec("ps ax | grep ruby | grep -v grep | grep -v #{Process.pid} | cut -b3-7 | xargs -t kill;", true);
|
390
422
|
l.done
|
391
423
|
# run the number of workers specified in the configuration of the Pampa module.
|
392
424
|
node.workers.each { |worker|
|
393
425
|
# run the worker
|
394
426
|
# add these parameters for debug: debug=yes pampa=~/code/pampa/lib/pampa.rb
|
427
|
+
# run a bash command that sources the .profile file and runs the ruby script in the background, returning immediatelly.
|
428
|
+
|
395
429
|
l.logs "Running worker #{worker.id}... "
|
396
|
-
|
397
|
-
|
430
|
+
|
431
|
+
# write bash command to initialize bash file
|
432
|
+
s = "echo \"source $HOME/.profile; cd #{BlackStack::Pampa.working_directory}; nohup ruby #{worker_filename} id=#{worker.id} config=#{self.config_filename} >/dev/null 2>&1 &\" > #{BlackStack::Pampa.working_directory}/worker.sh"
|
433
|
+
node.exec(s, false);
|
434
|
+
|
435
|
+
s = "nohup bash #{BlackStack::Pampa.working_directory}/worker.sh >/dev/null 2>&1 &"
|
436
|
+
node.exec(s, false);
|
437
|
+
|
398
438
|
l.done
|
399
439
|
}
|
400
440
|
# disconnect the node
|
@@ -411,7 +451,7 @@ module BlackStack
|
|
411
451
|
# Parameters:
|
412
452
|
# - config: relative path of the configuration file. Example: '../config.rb'
|
413
453
|
#
|
414
|
-
def self.stop(
|
454
|
+
def self.stop()
|
415
455
|
# validate: the connection string is not nil
|
416
456
|
raise "The connection string is nil" if @@connection_string.nil?
|
417
457
|
# validate: the connection string is not empty
|
@@ -429,7 +469,7 @@ module BlackStack
|
|
429
469
|
l.done
|
430
470
|
# kill all ruby processes except this one
|
431
471
|
l.logs("Killing all Ruby processes except this one... ")
|
432
|
-
|
472
|
+
node.exec("ps ax | grep ruby | grep -v grep | grep -v #{Process.pid} | cut -b3-7 | xargs -t kill;", false);
|
433
473
|
l.done
|
434
474
|
# disconnect the node
|
435
475
|
l.logs("Disconnecting... ")
|
@@ -439,10 +479,43 @@ module BlackStack
|
|
439
479
|
} # @@nodes.each do |node|
|
440
480
|
end
|
441
481
|
|
482
|
+
# get the node by `node_name`
|
483
|
+
# connect the nodes via ssh.
|
484
|
+
# get how many minutes the worker wrote the log file
|
485
|
+
# close the connection
|
486
|
+
def self.log_minutes_ago(node_name, worker_id)
|
487
|
+
# get the node
|
488
|
+
n = self.nodes.select { |n| n.name == node_name }.first
|
489
|
+
return nil if !n
|
490
|
+
# connect the node
|
491
|
+
n.connect()
|
492
|
+
# get the time of the last time the worker wrote the log file
|
493
|
+
s = n.exec("cat #{BlackStack::Pampa.working_directory}/worker.#{worker_id}.log | tail -n 1 | cut -b1-19", false).to_s.strip
|
494
|
+
# run bash command to get the difference in minutes beteen now and the last time the worker wrote the log file
|
495
|
+
s = n.exec("echo \"$(($(date +%s) - $(date -d '#{s}' +%s))) / 60\" | bc", false).to_s.strip
|
496
|
+
# disconnect the node
|
497
|
+
n.disconnect
|
498
|
+
# return the number of minutes
|
499
|
+
s
|
500
|
+
end # log_minutes_ago
|
501
|
+
|
502
|
+
# get the node usage of CPU, RAM, DISK, and NETWORK
|
503
|
+
# return a hash with the usage of CPU, RAM, DISK, and NETWORK
|
504
|
+
#
|
505
|
+
# sudo apt install sysstat
|
506
|
+
#
|
507
|
+
def self.node_usage(node_name)
|
508
|
+
ret = {}
|
509
|
+
# get the node
|
510
|
+
n = self.nodes.select { |n| n.name == node_name }.first
|
511
|
+
return nil if !n
|
512
|
+
n.usage
|
513
|
+
end # node_usage
|
514
|
+
|
442
515
|
# stub worker class
|
443
516
|
class Worker
|
444
517
|
# name to identify uniquely the worker
|
445
|
-
attr_accessor :id, :assigned_job, :attached
|
518
|
+
attr_accessor :id, :assigned_job, :attached, :node
|
446
519
|
# return an array with the errors found in the description of the job
|
447
520
|
def self.descriptor_errors(h)
|
448
521
|
errors = []
|
@@ -471,6 +544,10 @@ module BlackStack
|
|
471
544
|
def detach()
|
472
545
|
self.attached = false
|
473
546
|
end
|
547
|
+
# get the latest n lines of the log of this worker
|
548
|
+
def tail(n=10)
|
549
|
+
self.node.tail("#{BlackStack::Pampa.working_directory}/worker.#{self.id}.log", n)
|
550
|
+
end
|
474
551
|
end
|
475
552
|
|
476
553
|
# stub node class
|
@@ -500,7 +577,9 @@ module BlackStack
|
|
500
577
|
self.max_workers = h[:max_workers]
|
501
578
|
self.workers = []
|
502
579
|
self.max_workers.times do |i|
|
503
|
-
|
580
|
+
new_worker = BlackStack::Pampa::Worker.new({:id => "#{self.name}.#{(i+1).to_s}", :node => self.to_hash})
|
581
|
+
new_worker.node = self
|
582
|
+
self.workers << new_worker
|
504
583
|
end
|
505
584
|
end # def self.create(h)
|
506
585
|
# returh a hash descriptor of the node
|
@@ -569,6 +648,8 @@ module BlackStack
|
|
569
648
|
# stretch assignation/unassignation of workers
|
570
649
|
attr_accessor :max_pending_tasks
|
571
650
|
attr_accessor :max_assigned_workers
|
651
|
+
# tags in order to choose on which nodes the job will be executed
|
652
|
+
attr_accessor :tags
|
572
653
|
|
573
654
|
# return a hash descriptor of the job
|
574
655
|
def to_hash()
|
@@ -596,6 +677,7 @@ module BlackStack
|
|
596
677
|
:processing_function => self.processing_function.to_s,
|
597
678
|
:max_pending_tasks => self.max_pending_tasks,
|
598
679
|
:max_assigned_workers => self.max_assigned_workers,
|
680
|
+
:tags => self.tags
|
599
681
|
}
|
600
682
|
end
|
601
683
|
|
@@ -631,6 +713,7 @@ module BlackStack
|
|
631
713
|
self.processing_function = h[:processing_function]
|
632
714
|
self.max_pending_tasks = h[:max_pending_tasks]
|
633
715
|
self.max_assigned_workers = h[:max_assigned_workers]
|
716
|
+
self.tags = h[:tags].nil? ? [] : ( h[:tags].is_a?(Array) ? h[:tags] : [h[:tags].to_s] )
|
634
717
|
end
|
635
718
|
|
636
719
|
# returns an array of tasks pending to be processed by the worker.
|
@@ -785,6 +868,66 @@ module BlackStack
|
|
785
868
|
#
|
786
869
|
return i
|
787
870
|
end
|
871
|
+
|
872
|
+
# reporting method: idle
|
873
|
+
# reutrn the number of idle tasks.
|
874
|
+
# if the numbr if idle tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
|
875
|
+
def idle(max_tasks_to_show=25)
|
876
|
+
j = self
|
877
|
+
ret = j.selecting(max_tasks_to_show).size
|
878
|
+
ret = ret >= max_tasks_to_show ? "#{ret.to_label}+" : ret.to_label
|
879
|
+
ret
|
880
|
+
end # def idle
|
881
|
+
|
882
|
+
# reporting method: running
|
883
|
+
# return the number of running tasks.
|
884
|
+
# if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
|
885
|
+
def running(max_tasks_to_show=25)
|
886
|
+
j = self
|
887
|
+
ret = 0
|
888
|
+
BlackStack::Pampa::nodes.each { |n|
|
889
|
+
n.workers.each { |w|
|
890
|
+
ret += j.occupied_slots(w).size
|
891
|
+
break if ret>=max_tasks_to_show
|
892
|
+
}
|
893
|
+
}
|
894
|
+
ret = ret >= max_tasks_to_show ? "#{max_tasks_to_show}+" : ret.to_label
|
895
|
+
ret
|
896
|
+
end # def idle
|
897
|
+
|
898
|
+
# reporting method: running
|
899
|
+
# return the number of running tasks.
|
900
|
+
# if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
|
901
|
+
def failed(max_tasks_to_show=25)
|
902
|
+
j = self
|
903
|
+
q = "
|
904
|
+
SELECT *
|
905
|
+
FROM #{j.table.to_s}
|
906
|
+
WHERE COALESCE(#{j.field_success.to_s},true)=false
|
907
|
+
--AND #{j.field_end_time.to_s} IS NULL
|
908
|
+
--AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
|
909
|
+
LIMIT #{max_tasks_to_show}
|
910
|
+
"
|
911
|
+
ret = DB[q].all.size
|
912
|
+
ret = ret >= max_tasks_to_show ? "#{ret.to_label}+" : ret.to_label
|
913
|
+
ret
|
914
|
+
end # def idle
|
915
|
+
|
916
|
+
# reporting method: error_descriptions
|
917
|
+
# return an array of hashes { :id, :error_description } with the tasks that have an the success flag in false, error description.
|
918
|
+
# if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show` errors.
|
919
|
+
def error_descriptions(max_tasks_to_show=25)
|
920
|
+
j = self
|
921
|
+
q = "
|
922
|
+
SELECT #{j.field_primary_key.to_s} as id, #{j.field_error_description.to_s} as description
|
923
|
+
FROM #{j.table.to_s}
|
924
|
+
WHERE COALESCE(#{j.field_success.to_s},true)=false
|
925
|
+
--AND #{j.field_end_time.to_s} IS NULL
|
926
|
+
--AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
|
927
|
+
LIMIT #{max_tasks_to_show}
|
928
|
+
"
|
929
|
+
DB[q].all
|
930
|
+
end
|
788
931
|
end # class Job
|
789
932
|
end # module Pampa
|
790
933
|
end # module BlackStack
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pampa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leandro Daniel Sardi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|