pampa 2.0.17 → 2.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pampa.rb +155 -115
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbbd19e65301b23d9e1ce78458528c5bdeecb73f2d54047e2546df8ad54f229d
4
- data.tar.gz: aaea0b4f3b174b565cec083ff833c52b255aede1304757a2383f23057ea25f06
3
+ metadata.gz: 80cb43785569b54fd129e7ee1444f02824cf0afe85a7d231be0bfad3ab33d604
4
+ data.tar.gz: 85a89a2f3f050bbe35e8d2749d5db04f8f1994980a0c726917093982dacf904d
5
5
  SHA512:
6
- metadata.gz: 26472faf3ef44736e06ea39351fcc4380c7ba94f282051df49f12d2572190daca659603866f6a4275dc793b1408c992fa20310500ae74d28f283d6d75eac97ee
7
- data.tar.gz: 7893ba252991c1e5603b00372d5a719552a3134fdd1daed6ed168c28c9f6864ed8d36561fe531f8ffef11557c099f9340c14b8411177b96f6714e10c9f498250
6
+ metadata.gz: a3e1b83cfe5ab4aebd31583df38f15bc79201e0882643d7730e7ba5e3b685f90673761dfa1d51ae527861fb06c756700453da464ece938780a2231bf19dd38f2
7
+ data.tar.gz: a8d64fac4872f892f46d353d565d82b7faf48fbf3366d353e438948d318ed5c9a31a31ec4a22e87520a11183f9b5bc78f88bbc92a4eb6b4db39cfb669739f435
data/lib/pampa.rb CHANGED
@@ -159,77 +159,80 @@ module BlackStack
159
159
  raise "The connection string is blank" if @@connection_string.strip.empty?
160
160
  # getting logger
161
161
  l = self.logger()
162
- # get attached and unassigned workers
163
- l.logs "Getting attached and unassigned workers... "
164
- workers = BlackStack::Pampa.workers.select { |worker| worker.attached && worker.assigned_job.nil? }
165
- l.logf "done (#{workers.size.to_s})"
166
162
  # get the job this worker is working with
167
163
  BlackStack::Pampa.jobs.each { |job|
168
- if workers.size == 0
169
- l.logf "No more workers to assign."
170
- break
171
- end
172
-
173
- l.logs("job:#{job.name}... ")
174
- l.logs("Gettting assigned workers... ")
175
- assigned = BlackStack::Pampa.workers.select { |worker| worker.attached && worker.assigned_job.to_s == job.name.to_s }
176
- l.logf("done (#{assigned.size.to_s})")
177
-
178
- l.logs("Getting total pending tasks... ")
179
-
180
- pendings = job.selecting(job.max_pending_tasks)
181
- l.logf("done (#{pendings.size.to_s})")
182
-
183
- l.logs("Has 0 tasks?.... ")
184
- if pendings.size == 0
185
- l.logf("yes")
186
-
187
- l.logs("Unassigning all assigned workers... ")
188
- assigned.each { |w|
189
- l.logs("Unassigning worker #{w.id}... ")
190
- w.assigned_job = nil
191
- l.done
192
-
193
- l.logs("Adding worker #{w.id} to the list of unassigned... ")
194
- workers << w
195
- l.done
196
- }
197
- l.done
198
- else
199
- l.logf("no")
200
-
201
- l.logs("Reached :max_pending_tasks (#{job.max_pending_tasks}) and more than 1 assigned workers ?... ")
202
- if pendings.size < job.max_pending_tasks && assigned.size > 1
203
- l.logf("no")
204
-
205
- l.logs("Unassigning worker... ")
206
- w = assigned.first # TODO: find a worker with no pending tasks
207
- w.assigned_job = nil
208
- l.done
164
+ l.log ''
165
+ l.logs "job #{job.name}... "
166
+ # get attached and unassigned workers
167
+ l.logs "Getting attached and unassigned workers... "
168
+ workers = BlackStack::Pampa.workers.select { |w| w.attached && w.assigned_job.nil? }
169
+ l.logf "done (#{workers.size.to_s})"
170
+ # get the workers that match the filter
171
+ l.logs "Getting workers that match the filter... "
172
+ workers = workers.select { |w| w.id =~ job.filter_worker_id }
173
+ l.logf "done (#{workers.size.to_s})"
174
+ # if theere are workers
175
+ if workers.size > 0
176
+ l.logs("Gettting assigned workers... ")
177
+ assigned = BlackStack::Pampa.workers.select { |worker| worker.attached && worker.assigned_job.to_s == job.name.to_s }
178
+ l.logf("done (#{assigned.size.to_s})")
179
+
180
+ l.logs("Getting total pending (idle) tasks... ")
181
+ pendings = job.idle
182
+ l.logf("done (#{pendings.to_s})")
183
+
184
+ l.logs("0 pending tasks?.... ")
185
+ if pendings.size == 0
186
+ l.logf("yes")
209
187
 
210
- l.logs("Adding worker from the list of unassigned... ")
211
- workers << w
188
+ l.logs("Unassigning all assigned workers... ")
189
+ assigned.each { |w|
190
+ l.logs("Unassigning worker... ")
191
+ w.assigned_job = nil
192
+ workers << w # add worker back to the list of unassigned
193
+ l.logf "done (#{w.id})"
194
+ }
212
195
  l.done
213
196
  else
214
- l.logf("yes")
197
+ l.logf("no")
215
198
 
216
- l.logs("Reached :max_assigned_workers (#{job.max_assigned_workers}) and more than 0 assigned workers?... ")
217
- if assigned.size >= job.max_assigned_workers && assigned.size > 0
199
+ l.logs("Under :max_pending_tasks (#{job.max_pending_tasks}) and more than 1 assigned workers ?... ")
200
+ if pendings.size < job.max_pending_tasks && assigned.size > 1
218
201
  l.logf("yes")
202
+
203
+ while assigned.size > 1
204
+ l.logs("Unassigning worker... ")
205
+ w = assigned.pop # TODO: find a worker with no pending tasks
206
+ w.assigned_job = nil
207
+ workers << w # add worker back to the array of unassigned workers
208
+ l.logf "done (#{w.id})"
209
+ end
219
210
  else
220
211
  l.logf("no")
221
212
 
222
- l.logs("Assigning worker... ")
223
- w = workers.first
224
- w.assigned_job = job.name.to_sym
225
- l.done
226
-
227
- l.logs("Removing worker from the list of unassigned... ")
228
- workers.delete(w)
229
- l.done
230
- end
231
- end
232
- end
213
+ l.logs("Over :max_assigned_workers (#{job.max_assigned_workers}) and more than 1 assigned workers?... ")
214
+ if assigned.size >= job.max_assigned_workers && assigned.size > 1
215
+ l.logf("yes")
216
+ else
217
+ l.logf("no")
218
+
219
+ i = assigned.size
220
+ while i < job.max_assigned_workers
221
+ i += 1
222
+ l.logs("Assigning worker... ")
223
+ w = workers.pop
224
+ if w.nil?
225
+ l.logf("no more workers")
226
+ break
227
+ else
228
+ w.assigned_job = job.name.to_sym
229
+ l.logf "done (#{w.id})"
230
+ end
231
+ end # while i < job.max_assigned_workers
232
+ end # if assigned.size >= job.max_assigned_workers && assigned.size > 0
233
+ end # if pendings.size < job.max_pending_tasks && assigned.size > 1
234
+ end # if pendings.size == 0
235
+ end # if workers.size > 0
233
236
  l.done
234
237
  }
235
238
  end
@@ -431,7 +434,6 @@ module BlackStack
431
434
  cd #{BlackStack::Pampa.working_directory};
432
435
  nohup ruby #{worker_filename} id=#{worker.id} config=#{self.config_filename} >/dev/null 2>&1 &
433
436
  \" > #{BlackStack::Pampa.working_directory}/#{worker.id}.sh"
434
- #binding.pry
435
437
  node.exec(s, false);
436
438
  s = "nohup bash #{BlackStack::Pampa.working_directory}/#{worker.id}.sh >/dev/null 2>&1 &"
437
439
  node.exec(s, false);
@@ -484,6 +486,9 @@ module BlackStack
484
486
  # connect the nodes via ssh.
485
487
  # get how many minutes the worker wrote the log file
486
488
  # close the connection
489
+ #
490
+ # DEPRECATED. Use `ps aux | grep "..."` to know if a process is running or not.
491
+ #
487
492
  def self.log_minutes_ago(node_name, worker_id)
488
493
  # get the node
489
494
  n = self.nodes.select { |n| n.name == node_name }.first
@@ -659,8 +664,8 @@ module BlackStack
659
664
  # stretch assignation/unassignation of workers
660
665
  attr_accessor :max_pending_tasks
661
666
  attr_accessor :max_assigned_workers
662
- # tags in order to choose on which nodes the job will be executed
663
- attr_accessor :tags
667
+ # choose workers to assign tasks
668
+ attr_accessor :filter_worker_id
664
669
 
665
670
  # return a hash descriptor of the job
666
671
  def to_hash()
@@ -688,7 +693,7 @@ module BlackStack
688
693
  :processing_function => self.processing_function.to_s,
689
694
  :max_pending_tasks => self.max_pending_tasks,
690
695
  :max_assigned_workers => self.max_assigned_workers,
691
- :tags => self.tags
696
+ :filter_worker_id => self.filter_worker_id
692
697
  }
693
698
  end
694
699
 
@@ -724,7 +729,7 @@ module BlackStack
724
729
  self.processing_function = h[:processing_function]
725
730
  self.max_pending_tasks = h[:max_pending_tasks]
726
731
  self.max_assigned_workers = h[:max_assigned_workers]
727
- self.tags = h[:tags].nil? ? [] : ( h[:tags].is_a?(Array) ? h[:tags] : [h[:tags].to_s] )
732
+ self.filter_worker_id = h[:filter_worker_id]
728
733
  end
729
734
 
730
735
  # returns an array of tasks pending to be processed by the worker.
@@ -806,7 +811,17 @@ module BlackStack
806
811
  end
807
812
 
808
813
  def update(o)
809
- DB[self.table.to_sym].where(
814
+ # use the select to update ONLY the pampa fields.
815
+ DB[self.table.to_sym].select(
816
+ :field_primary_key,
817
+ :field_id,
818
+ :field_time,
819
+ :field_times,
820
+ :field_start_time,
821
+ :field_end_time,
822
+ :field_success,
823
+ :field_error_description
824
+ ).where(
810
825
  self.field_primary_key.to_sym => o[self.field_primary_key.to_sym]
811
826
  ).update(o)
812
827
  end
@@ -864,69 +879,96 @@ module BlackStack
864
879
  # dispatching n pending records
865
880
  i = 0
866
881
  if n>0
867
- self.selecting(n).each { |o|
868
- # count the # of dispatched
869
- i += 1
870
- # dispatch
871
- o[self.field_id.to_sym] = worker.id
872
- o[self.field_time.to_sym] = DB["SELECT CAST('#{BlackStack::Pampa.now}' AS TIMESTAMP) AS dt"].first[:dt] # IMPORTANT: use DB location to get current time.
873
- o[self.field_start_time.to_sym] = nil if !self.field_start_time.nil?
874
- o[self.field_end_time.to_sym] = nil if !self.field_end_time.nil?
875
- self.update(o)
876
- # release resources
877
- DB.disconnect
878
- GC.start
879
- }
882
+ ids = self.selecting(n).map { |h| h[:id] }
883
+
884
+ i = ids.size
885
+ q = "
886
+ UPDATE #{self.table.to_s}
887
+ SET
888
+ #{self.field_id.to_s} = '#{worker.id}',
889
+ "
890
+
891
+ if !self.field_start_time.nil?
892
+ q += "
893
+ #{self.field_start_time.to_s} = NULL,
894
+ "
895
+ end
896
+
897
+ if !self.field_end_time.nil?
898
+ q += "
899
+ #{self.field_end_time.to_s} = NULL,
900
+ "
901
+ end
902
+
903
+ q += "
904
+ #{self.field_time.to_s} = CAST('#{BlackStack::Pampa.now}' AS TIMESTAMP)
905
+ WHERE #{self.field_primary_key.to_s} IN ('#{ids.join("','")}')
906
+ "
907
+
908
+ DB.execute(q)
880
909
  end
881
910
 
882
911
  #
883
912
  return i
884
913
  end
885
914
 
915
+ # reporting methods
916
+ # idle + failed + completed = total
917
+
886
918
  # reporting method: idle
887
919
  # reutrn the number of idle tasks.
888
920
  # if the numbr if idle tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
889
- def idle(max_tasks_to_show=25)
890
- j = self
891
- ret = j.selecting(max_tasks_to_show).size
892
- ret = ret >= max_tasks_to_show ? "#{ret.to_label}+" : ret.to_label
893
- ret
894
- end # def idle
921
+ def total
922
+ j = self
923
+ q = "
924
+ SELECT COUNT(*) AS n
925
+ FROM #{j.table.to_s}
926
+ "
927
+ DB[q].first[:n].to_i
928
+ end # def total
895
929
 
896
- # reporting method: running
897
- # return the number of running tasks.
898
- # if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
899
- def running(max_tasks_to_show=25)
900
- j = self
901
- ret = 0
902
- BlackStack::Pampa::nodes.each { |n|
903
- n.workers.each { |w|
904
- ret += j.occupied_slots(w).size
905
- break if ret>=max_tasks_to_show
906
- }
907
- }
908
- ret = ret >= max_tasks_to_show ? "#{max_tasks_to_show}+" : ret.to_label
909
- ret
910
- end # def idle
911
930
 
912
- # reporting method: running
913
- # return the number of running tasks.
914
- # if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
915
- def failed(max_tasks_to_show=25)
931
+ # reporting method: idle
932
+ # reutrn the number of idle tasks.
933
+ # if the numbr if idle tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
934
+ def completed
935
+ j = self
936
+ q = "
937
+ SELECT COUNT(*) AS n
938
+ FROM #{j.table.to_s}
939
+ WHERE COALESCE(#{j.field_success.to_s},false)=true
940
+ "
941
+ DB[q].first[:n].to_i
942
+ end # def completed
943
+
944
+ # reporting method: idle
945
+ # reutrn the number of idle tasks.
946
+ # if the numbr if idle tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
947
+ def idle
916
948
  j = self
917
949
  q = "
918
- SELECT *
950
+ SELECT COUNT(*) AS n
919
951
  FROM #{j.table.to_s}
920
- WHERE COALESCE(#{j.field_success.to_s},true)=false
921
- --AND #{j.field_end_time.to_s} IS NULL
922
- --AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
923
- LIMIT #{max_tasks_to_show}
952
+ WHERE COALESCE(#{j.field_success.to_s},false)=false
953
+ AND COALESCE(#{j.field_times.to_s},0) < #{j.max_try_times.to_i}
924
954
  "
925
- ret = DB[q].all.size
926
- ret = ret >= max_tasks_to_show ? "#{ret.to_label}+" : ret.to_label
927
- ret
955
+ DB[q].first[:n].to_i
928
956
  end # def idle
929
957
 
958
+ # reporting method: running
959
+ # return the number of running tasks.
960
+ # if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show`+.
961
+ def failed
962
+ j = self
963
+ q = "
964
+ SELECT COUNT(*) AS n
965
+ FROM #{j.table.to_s}
966
+ WHERE COALESCE(#{j.field_success.to_s},false)=false
967
+ AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
968
+ "
969
+ DB[q].first[:n].to_i
970
+ end # def falsed
971
+
930
972
  # reporting method: error_descriptions
931
973
  # return an array of hashes { :id, :error_description } with the tasks that have an the success flag in false, error description.
932
974
  # if the numbr if running tasks is higher than `max_tasks_to_show` then it returns `max_tasks_to_show` errors.
@@ -936,8 +978,6 @@ module BlackStack
936
978
  SELECT #{j.field_primary_key.to_s} as id, #{j.field_error_description.to_s} as description
937
979
  FROM #{j.table.to_s}
938
980
  WHERE COALESCE(#{j.field_success.to_s},true)=false
939
- --AND #{j.field_end_time.to_s} IS NULL
940
- --AND COALESCE(#{j.field_times.to_s},0) >= #{j.max_try_times.to_i}
941
981
  LIMIT #{max_tasks_to_show}
942
982
  "
943
983
  DB[q].all
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.17
4
+ version: 2.0.18
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-01-18 00:00:00.000000000 Z
11
+ date: 2022-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel