pampa 2.0.12 → 2.0.15
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 +210 -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: a8627e0b3e3f9d923c9dc750fde056078bfd202a74e3abd36eecfa27566c93f3
|
4
|
+
data.tar.gz: 27990d2b64539c229974280e5d80b630b7e6dfb05b4b6533ef8976031e791a7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71fb9a3ab3965c5aa591412c358ff6074b12d9e7ff6b8409d941ac28e42ba2ccb85288f1987a20758fd81c795d22323c597c2f15be040d5e1b628fed008aaecb
|
7
|
+
data.tar.gz: e33cfc7bca76c0a3031c4bfdc96417cfba6fadbcf7593b499a9eb2b5cefd996371b05548f159149ff2d204ae8035c524ac77c2dadbb081bde93693f0e64da1d9
|
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,48 @@ 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.kill_workers()
|
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
|
-
|
355
|
-
|
386
|
+
|
387
|
+
# write bash command to initialize bash file
|
388
|
+
s = "echo \"
|
389
|
+
export RUBYLIB=$HOME/code/mysaas;
|
390
|
+
source $HOME/.profile;
|
391
|
+
source /usr/local/rvm/scripts/rvm;
|
392
|
+
cd ~/code/mysaas; rvm install 3.1.2;
|
393
|
+
rvm --default use 3.1.2;
|
394
|
+
cd #{BlackStack::Pampa.working_directory};
|
395
|
+
nohup ruby #{worker_filename} id=#{worker.id} config=#{self.config_filename} >/dev/null 2>&1 &
|
396
|
+
\" > #{BlackStack::Pampa.working_directory}/#{worker.id}.sh"
|
397
|
+
node.exec(s, false);
|
398
|
+
|
399
|
+
#s = "nohup bash #{BlackStack::Pampa.working_directory}/worker.sh >/dev/null 2>&1 &"
|
400
|
+
s = "bash #{BlackStack::Pampa.working_directory}/#{worker.id}.sh"
|
401
|
+
node.exec(s, false);
|
402
|
+
|
356
403
|
l.done
|
357
404
|
}
|
358
405
|
# disconnect the node
|
@@ -368,7 +415,7 @@ module BlackStack
|
|
368
415
|
# run the number of workers specified in the configuration of the Pampa module.
|
369
416
|
# return an array with the IDs of the workers.
|
370
417
|
#
|
371
|
-
def self.start(
|
418
|
+
def self.start()
|
372
419
|
# validate: the connection string is not nil
|
373
420
|
raise "The connection string is nil" if @@connection_string.nil?
|
374
421
|
# validate: the connection string is not empty
|
@@ -386,15 +433,31 @@ module BlackStack
|
|
386
433
|
l.done
|
387
434
|
# kill all ruby processes except this one
|
388
435
|
l.logs("Killing all Ruby processes except this one... ")
|
389
|
-
|
436
|
+
node.kill_workers()
|
390
437
|
l.done
|
391
438
|
# run the number of workers specified in the configuration of the Pampa module.
|
392
439
|
node.workers.each { |worker|
|
393
440
|
# run the worker
|
394
441
|
# add these parameters for debug: debug=yes pampa=~/code/pampa/lib/pampa.rb
|
442
|
+
# run a bash command that sources the .profile file and runs the ruby script in the background, returning immediatelly.
|
443
|
+
|
395
444
|
l.logs "Running worker #{worker.id}... "
|
396
|
-
|
397
|
-
|
445
|
+
|
446
|
+
# write bash command to initialize bash file
|
447
|
+
s = "echo \"
|
448
|
+
export RUBYLIB=$HOME/code/mysaas;
|
449
|
+
source $HOME/.profile;
|
450
|
+
source /usr/local/rvm/scripts/rvm;
|
451
|
+
cd ~/code/mysaas; rvm install 3.1.2;
|
452
|
+
rvm --default use 3.1.2;
|
453
|
+
cd #{BlackStack::Pampa.working_directory};
|
454
|
+
nohup ruby #{worker_filename} id=#{worker.id} config=#{self.config_filename} >/dev/null 2>&1 &
|
455
|
+
\" > #{BlackStack::Pampa.working_directory}/#{worker.id}.sh"
|
456
|
+
#binding.pry
|
457
|
+
node.exec(s, false);
|
458
|
+
s = "nohup bash #{BlackStack::Pampa.working_directory}/#{worker.id}.sh >/dev/null 2>&1 &"
|
459
|
+
node.exec(s, false);
|
460
|
+
|
398
461
|
l.done
|
399
462
|
}
|
400
463
|
# disconnect the node
|
@@ -411,7 +474,7 @@ module BlackStack
|
|
411
474
|
# Parameters:
|
412
475
|
# - config: relative path of the configuration file. Example: '../config.rb'
|
413
476
|
#
|
414
|
-
def self.stop(
|
477
|
+
def self.stop()
|
415
478
|
# validate: the connection string is not nil
|
416
479
|
raise "The connection string is nil" if @@connection_string.nil?
|
417
480
|
# validate: the connection string is not empty
|
@@ -429,7 +492,7 @@ module BlackStack
|
|
429
492
|
l.done
|
430
493
|
# kill all ruby processes except this one
|
431
494
|
l.logs("Killing all Ruby processes except this one... ")
|
432
|
-
|
495
|
+
node.kill_workers()
|
433
496
|
l.done
|
434
497
|
# disconnect the node
|
435
498
|
l.logs("Disconnecting... ")
|
@@ -439,10 +502,44 @@ module BlackStack
|
|
439
502
|
} # @@nodes.each do |node|
|
440
503
|
end
|
441
504
|
|
505
|
+
# get the node by `node_name`
|
506
|
+
# connect the nodes via ssh.
|
507
|
+
# get how many minutes the worker wrote the log file
|
508
|
+
# close the connection
|
509
|
+
def self.log_minutes_ago(node_name, worker_id)
|
510
|
+
# get the node
|
511
|
+
n = self.nodes.select { |n| n.name == node_name }.first
|
512
|
+
return nil if !n
|
513
|
+
# connect the node
|
514
|
+
n.connect()
|
515
|
+
# get the time of the last time the worker wrote the log file
|
516
|
+
code = "cat #{BlackStack::Pampa.working_directory}/worker.#{worker_id}.log | tail -n 1 | cut -b1-19"
|
517
|
+
s = n.exec(code, false).to_s.strip
|
518
|
+
# run bash command to get the difference in minutes beteen now and the last time the worker wrote the log file
|
519
|
+
s = n.exec("echo \"$(($(date +%s) - $(date -d '#{s}' +%s))) / 60\" | bc", false).to_s.strip
|
520
|
+
# disconnect the node
|
521
|
+
n.disconnect
|
522
|
+
# return the number of minutes
|
523
|
+
s
|
524
|
+
end # log_minutes_ago
|
525
|
+
|
526
|
+
# get the node usage of CPU, RAM, DISK, and NETWORK
|
527
|
+
# return a hash with the usage of CPU, RAM, DISK, and NETWORK
|
528
|
+
#
|
529
|
+
# sudo apt install sysstat
|
530
|
+
#
|
531
|
+
def self.node_usage(node_name)
|
532
|
+
ret = {}
|
533
|
+
# get the node
|
534
|
+
n = self.nodes.select { |n| n.name == node_name }.first
|
535
|
+
return nil if !n
|
536
|
+
n.usage
|
537
|
+
end # node_usage
|
538
|
+
|
442
539
|
# stub worker class
|
443
540
|
class Worker
|
444
541
|
# name to identify uniquely the worker
|
445
|
-
attr_accessor :id, :assigned_job, :attached
|
542
|
+
attr_accessor :id, :assigned_job, :attached, :node
|
446
543
|
# return an array with the errors found in the description of the job
|
447
544
|
def self.descriptor_errors(h)
|
448
545
|
errors = []
|
@@ -471,6 +568,10 @@ module BlackStack
|
|
471
568
|
def detach()
|
472
569
|
self.attached = false
|
473
570
|
end
|
571
|
+
# get the latest n lines of the log of this worker
|
572
|
+
def tail(n=10)
|
573
|
+
self.node.tail("#{BlackStack::Pampa.working_directory}/worker.#{self.id}.log", n)
|
574
|
+
end
|
474
575
|
end
|
475
576
|
|
476
577
|
# stub node class
|
@@ -500,7 +601,9 @@ module BlackStack
|
|
500
601
|
self.max_workers = h[:max_workers]
|
501
602
|
self.workers = []
|
502
603
|
self.max_workers.times do |i|
|
503
|
-
|
604
|
+
new_worker = BlackStack::Pampa::Worker.new({:id => "#{self.name}.#{(i+1).to_s}", :node => self.to_hash})
|
605
|
+
new_worker.node = self
|
606
|
+
self.workers << new_worker
|
504
607
|
end
|
505
608
|
end # def self.create(h)
|
506
609
|
# returh a hash descriptor of the node
|
@@ -513,6 +616,15 @@ module BlackStack
|
|
513
616
|
end
|
514
617
|
ret
|
515
618
|
end
|
619
|
+
# kill all workers
|
620
|
+
def kill_workers()
|
621
|
+
self.workers.each do |worker|
|
622
|
+
self.kill_worker(worker.id)
|
623
|
+
end
|
624
|
+
end
|
625
|
+
def kill_worker(worker_id)
|
626
|
+
self.exec("kill -9 $(ps -ef | grep \"ruby worker.rb id=#{worker_id}\" | grep -v grep | awk '{print $2}')", false)
|
627
|
+
end
|
516
628
|
end # class Node
|
517
629
|
|
518
630
|
# stub job class
|
@@ -569,6 +681,8 @@ module BlackStack
|
|
569
681
|
# stretch assignation/unassignation of workers
|
570
682
|
attr_accessor :max_pending_tasks
|
571
683
|
attr_accessor :max_assigned_workers
|
684
|
+
# tags in order to choose on which nodes the job will be executed
|
685
|
+
attr_accessor :tags
|
572
686
|
|
573
687
|
# return a hash descriptor of the job
|
574
688
|
def to_hash()
|
@@ -596,6 +710,7 @@ module BlackStack
|
|
596
710
|
:processing_function => self.processing_function.to_s,
|
597
711
|
:max_pending_tasks => self.max_pending_tasks,
|
598
712
|
:max_assigned_workers => self.max_assigned_workers,
|
713
|
+
:tags => self.tags
|
599
714
|
}
|
600
715
|
end
|
601
716
|
|
@@ -631,6 +746,7 @@ module BlackStack
|
|
631
746
|
self.processing_function = h[:processing_function]
|
632
747
|
self.max_pending_tasks = h[:max_pending_tasks]
|
633
748
|
self.max_assigned_workers = h[:max_assigned_workers]
|
749
|
+
self.tags = h[:tags].nil? ? [] : ( h[:tags].is_a?(Array) ? h[:tags] : [h[:tags].to_s] )
|
634
750
|
end
|
635
751
|
|
636
752
|
# returns an array of tasks pending to be processed by the worker.
|
@@ -785,6 +901,66 @@ module BlackStack
|
|
785
901
|
#
|
786
902
|
return i
|
787
903
|
end
|
904
|
+
|
905
|
+
# reporting method: idle
|
906
|
+
# reutrn the number of idle tasks.
|
907
|
+
# if the numbr if idle tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
|
908
|
+
def idle(max_tasks_to_show=25)
|
909
|
+
j = self
|
910
|
+
ret = j.selecting(max_tasks_to_show).size
|
911
|
+
ret = ret >= max_tasks_to_show ? "#{ret.to_label}+" : ret.to_label
|
912
|
+
ret
|
913
|
+
end # def idle
|
914
|
+
|
915
|
+
# reporting method: running
|
916
|
+
# return the number of running tasks.
|
917
|
+
# if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
|
918
|
+
def running(max_tasks_to_show=25)
|
919
|
+
j = self
|
920
|
+
ret = 0
|
921
|
+
BlackStack::Pampa::nodes.each { |n|
|
922
|
+
n.workers.each { |w|
|
923
|
+
ret += j.occupied_slots(w).size
|
924
|
+
break if ret>=max_tasks_to_show
|
925
|
+
}
|
926
|
+
}
|
927
|
+
ret = ret >= max_tasks_to_show ? "#{max_tasks_to_show}+" : ret.to_label
|
928
|
+
ret
|
929
|
+
end # def idle
|
930
|
+
|
931
|
+
# reporting method: running
|
932
|
+
# return the number of running tasks.
|
933
|
+
# if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
|
934
|
+
def failed(max_tasks_to_show=25)
|
935
|
+
j = self
|
936
|
+
q = "
|
937
|
+
SELECT *
|
938
|
+
FROM #{j.table.to_s}
|
939
|
+
WHERE COALESCE(#{j.field_success.to_s},true)=false
|
940
|
+
--AND #{j.field_end_time.to_s} IS NULL
|
941
|
+
--AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
|
942
|
+
LIMIT #{max_tasks_to_show}
|
943
|
+
"
|
944
|
+
ret = DB[q].all.size
|
945
|
+
ret = ret >= max_tasks_to_show ? "#{ret.to_label}+" : ret.to_label
|
946
|
+
ret
|
947
|
+
end # def idle
|
948
|
+
|
949
|
+
# reporting method: error_descriptions
|
950
|
+
# return an array of hashes { :id, :error_description } with the tasks that have an the success flag in false, error description.
|
951
|
+
# if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show` errors.
|
952
|
+
def error_descriptions(max_tasks_to_show=25)
|
953
|
+
j = self
|
954
|
+
q = "
|
955
|
+
SELECT #{j.field_primary_key.to_s} as id, #{j.field_error_description.to_s} as description
|
956
|
+
FROM #{j.table.to_s}
|
957
|
+
WHERE COALESCE(#{j.field_success.to_s},true)=false
|
958
|
+
--AND #{j.field_end_time.to_s} IS NULL
|
959
|
+
--AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
|
960
|
+
LIMIT #{max_tasks_to_show}
|
961
|
+
"
|
962
|
+
DB[q].all
|
963
|
+
end
|
788
964
|
end # class Job
|
789
965
|
end # module Pampa
|
790
966
|
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.15
|
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-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|