rbbt-util 5.44.1 → 6.0.4

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 (175) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/bin/rbbt +67 -90
  4. data/bin/rbbt_exec.rb +2 -2
  5. data/etc/app.d/base.rb +2 -2
  6. data/etc/app.d/semaphores.rb +3 -3
  7. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  8. data/lib/rbbt/annotations/refactor.rb +27 -0
  9. data/lib/rbbt/annotations/util.rb +282 -282
  10. data/lib/rbbt/annotations.rb +343 -320
  11. data/lib/rbbt/association/database.rb +200 -225
  12. data/lib/rbbt/association/index.rb +294 -291
  13. data/lib/rbbt/association/item.rb +227 -227
  14. data/lib/rbbt/association/open.rb +35 -34
  15. data/lib/rbbt/association/util.rb +0 -169
  16. data/lib/rbbt/association.rb +2 -4
  17. data/lib/rbbt/entity/identifiers.rb +119 -118
  18. data/lib/rbbt/entity/refactor.rb +12 -0
  19. data/lib/rbbt/entity.rb +319 -315
  20. data/lib/rbbt/hpc/batch.rb +72 -53
  21. data/lib/rbbt/hpc/lsf.rb +2 -2
  22. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  24. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  25. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  26. data/lib/rbbt/hpc/slurm.rb +18 -18
  27. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  28. data/lib/rbbt/knowledge_base/query.rb +2 -2
  29. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  30. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  31. data/lib/rbbt/knowledge_base.rb +1 -1
  32. data/lib/rbbt/monitor.rb +36 -25
  33. data/lib/rbbt/persist/refactor.rb +166 -0
  34. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  35. data/lib/rbbt/persist/tsv.rb +187 -185
  36. data/lib/rbbt/persist.rb +556 -551
  37. data/lib/rbbt/refactor.rb +20 -0
  38. data/lib/rbbt/resource/path/refactor.rb +178 -0
  39. data/lib/rbbt/resource/path.rb +317 -497
  40. data/lib/rbbt/resource/util.rb +0 -48
  41. data/lib/rbbt/resource.rb +3 -390
  42. data/lib/rbbt/tsv/accessor.rb +2 -838
  43. data/lib/rbbt/tsv/attach.rb +303 -299
  44. data/lib/rbbt/tsv/change_id.rb +244 -245
  45. data/lib/rbbt/tsv/csv.rb +87 -85
  46. data/lib/rbbt/tsv/dumper.rb +2 -100
  47. data/lib/rbbt/tsv/excel.rb +26 -24
  48. data/lib/rbbt/tsv/field_index.rb +4 -1
  49. data/lib/rbbt/tsv/filter.rb +3 -2
  50. data/lib/rbbt/tsv/index.rb +2 -284
  51. data/lib/rbbt/tsv/manipulate.rb +750 -747
  52. data/lib/rbbt/tsv/marshal.rb +3 -3
  53. data/lib/rbbt/tsv/matrix.rb +2 -2
  54. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  55. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  56. data/lib/rbbt/tsv/parser.rb +678 -678
  57. data/lib/rbbt/tsv/refactor.rb +195 -0
  58. data/lib/rbbt/tsv/stream.rb +253 -251
  59. data/lib/rbbt/tsv/util.rb +420 -420
  60. data/lib/rbbt/tsv.rb +210 -208
  61. data/lib/rbbt/util/R/eval.rb +4 -4
  62. data/lib/rbbt/util/R/plot.rb +62 -166
  63. data/lib/rbbt/util/R.rb +21 -18
  64. data/lib/rbbt/util/cmd.rb +2 -318
  65. data/lib/rbbt/util/color.rb +269 -269
  66. data/lib/rbbt/util/colorize.rb +89 -89
  67. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  68. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  69. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  70. data/lib/rbbt/util/config.rb +169 -167
  71. data/lib/rbbt/util/filecache.rb +1 -1
  72. data/lib/rbbt/util/iruby.rb +20 -0
  73. data/lib/rbbt/util/log/progress/report.rb +241 -241
  74. data/lib/rbbt/util/log/progress/util.rb +99 -99
  75. data/lib/rbbt/util/log/progress.rb +102 -102
  76. data/lib/rbbt/util/log/refactor.rb +49 -0
  77. data/lib/rbbt/util/log.rb +486 -532
  78. data/lib/rbbt/util/migrate.rb +2 -2
  79. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  80. data/lib/rbbt/util/misc/development.rb +12 -11
  81. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  82. data/lib/rbbt/util/misc/format.rb +2 -230
  83. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  84. data/lib/rbbt/util/misc/inspect.rb +2 -476
  85. data/lib/rbbt/util/misc/lock.rb +109 -106
  86. data/lib/rbbt/util/misc/omics.rb +9 -1
  87. data/lib/rbbt/util/misc/pipes.rb +765 -793
  88. data/lib/rbbt/util/misc/refactor.rb +20 -0
  89. data/lib/rbbt/util/misc/ssw.rb +27 -17
  90. data/lib/rbbt/util/misc/system.rb +92 -105
  91. data/lib/rbbt/util/misc.rb +39 -20
  92. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  93. data/lib/rbbt/util/named_array.rb +3 -220
  94. data/lib/rbbt/util/open/refactor.rb +7 -0
  95. data/lib/rbbt/util/open.rb +3 -857
  96. data/lib/rbbt/util/procpath.rb +6 -6
  97. data/lib/rbbt/util/python/paths.rb +27 -0
  98. data/lib/rbbt/util/python/run.rb +115 -0
  99. data/lib/rbbt/util/python/script.rb +110 -0
  100. data/lib/rbbt/util/python/util.rb +3 -3
  101. data/lib/rbbt/util/python.rb +22 -81
  102. data/lib/rbbt/util/semaphore.rb +152 -148
  103. data/lib/rbbt/util/simpleopt.rb +9 -8
  104. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  105. data/lib/rbbt/util/ssh.rb +122 -118
  106. data/lib/rbbt/util/tar.rb +117 -115
  107. data/lib/rbbt/util/tmpfile.rb +69 -67
  108. data/lib/rbbt/util/version.rb +2 -0
  109. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  110. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  111. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  112. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  113. data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
  114. data/lib/rbbt/workflow/refactor.rb +150 -0
  115. data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
  116. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  117. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  118. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  119. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  120. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  121. data/lib/rbbt/workflow/step/run.rb +766 -766
  122. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  123. data/lib/rbbt/workflow/step.rb +2 -362
  124. data/lib/rbbt/workflow/task.rb +118 -118
  125. data/lib/rbbt/workflow/usage.rb +289 -287
  126. data/lib/rbbt/workflow/util/archive.rb +6 -5
  127. data/lib/rbbt/workflow/util/data.rb +1 -1
  128. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  129. data/lib/rbbt/workflow/util/trace.rb +79 -44
  130. data/lib/rbbt/workflow.rb +4 -882
  131. data/lib/rbbt-util.rb +21 -13
  132. data/lib/rbbt.rb +16 -3
  133. data/python/rbbt/__init__.py +96 -4
  134. data/python/rbbt/workflow/remote.py +104 -0
  135. data/python/rbbt/workflow.py +64 -0
  136. data/python/test.py +10 -0
  137. data/share/Rlib/plot.R +37 -37
  138. data/share/Rlib/svg.R +22 -5
  139. data/share/install/software/lib/install_helpers +1 -1
  140. data/share/rbbt_commands/hpc/list +2 -3
  141. data/share/rbbt_commands/hpc/orchestrate +4 -4
  142. data/share/rbbt_commands/hpc/tail +2 -0
  143. data/share/rbbt_commands/hpc/task +10 -7
  144. data/share/rbbt_commands/lsf/list +2 -3
  145. data/share/rbbt_commands/lsf/orchestrate +4 -4
  146. data/share/rbbt_commands/lsf/tail +2 -0
  147. data/share/rbbt_commands/lsf/task +10 -7
  148. data/share/rbbt_commands/migrate +1 -1
  149. data/share/rbbt_commands/pbs/list +2 -3
  150. data/share/rbbt_commands/pbs/orchestrate +4 -4
  151. data/share/rbbt_commands/pbs/tail +2 -0
  152. data/share/rbbt_commands/pbs/task +10 -7
  153. data/share/rbbt_commands/resource/produce +8 -1
  154. data/share/rbbt_commands/slurm/list +2 -3
  155. data/share/rbbt_commands/slurm/orchestrate +4 -4
  156. data/share/rbbt_commands/slurm/tail +2 -0
  157. data/share/rbbt_commands/slurm/task +10 -7
  158. data/share/rbbt_commands/system/clean +5 -5
  159. data/share/rbbt_commands/system/status +5 -5
  160. data/share/rbbt_commands/tsv/get +2 -3
  161. data/share/rbbt_commands/tsv/info +10 -13
  162. data/share/rbbt_commands/tsv/keys +18 -14
  163. data/share/rbbt_commands/tsv/slice +2 -2
  164. data/share/rbbt_commands/tsv/transpose +6 -2
  165. data/share/rbbt_commands/workflow/info +20 -24
  166. data/share/rbbt_commands/workflow/list +1 -1
  167. data/share/rbbt_commands/workflow/prov +20 -13
  168. data/share/rbbt_commands/workflow/retry +43 -0
  169. data/share/rbbt_commands/workflow/server +12 -2
  170. data/share/rbbt_commands/workflow/task +80 -73
  171. data/share/rbbt_commands/workflow/write_info +26 -9
  172. data/share/software/opt/ssw/ssw.c +861 -0
  173. data/share/software/opt/ssw/ssw.h +130 -0
  174. data/share/workflow_config.ru +3 -3
  175. metadata +45 -6
@@ -1,386 +1,389 @@
1
- require 'rbbt/util/concurrency/processes/worker'
2
- require 'rbbt/util/concurrency/processes/socket'
3
-
4
- class RbbtProcessQueue
5
-
6
- attr_accessor :num_processes, :queue, :process_monitor, :cleanup, :join, :reswpan, :offset
7
- def initialize(num_processes, cleanup = nil, join = nil, reswpan = nil, offset = false)
8
- @num_processes = num_processes
9
- @cleanup = cleanup
10
- @join = join
11
- @respawn = reswpan
12
- @offset = offset
13
- @queue = RbbtProcessSocket.new
14
-
15
- key = "/" << rand(1000000000).to_s << '.' << Process.pid.to_s;
16
- @sem = key + '.process'
17
- Log.debug "Creating process semaphore: #{@sem}"
18
- RbbtSemaphore.create_semaphore(@sem,1)
19
- end
20
-
21
-
22
- ABORT_SIGNAL = :INT
23
- CLOSE_SIGNAL = :PIPE
24
-
25
- attr_accessor :callback, :callback_queue, :callback_thread
26
- def callback(&block)
27
- if block_given?
28
-
29
- @callback = block
30
-
31
- @callback_queue = RbbtProcessSocket.new
32
-
33
- else
34
- @callback, @callback_queue, @callback_thread = nil, nil, nil
35
- end
36
- end
37
-
38
- def init_master
39
- RbbtSemaphore.wait_semaphore(@sem)
40
- @master_pid = Process.fork do
41
- @close_up = false
42
- processes_initiated = false
43
- processes = []
44
- process_mutex = Mutex.new
45
-
46
- Signal.trap(CLOSE_SIGNAL) do
47
- if ! @closing_thread
48
- @close_up = true
49
- Misc.insist([0,0.01,0.1,0.2,0.5]) do
50
- if ! @manager_thread
51
- Thread.pass
52
- raise "Manager thread for #{Process.pid} not found yet"
53
- end
54
-
55
- if @manager_thread.alive?
56
- raise "Manager thread for #{Process.pid} not working yet" unless @manager_thread["working"]
57
- @manager_thread.raise TryAgain
58
- end
59
- end
60
- end
61
- end
62
-
63
- Signal.trap(:USR1) do
64
- @count += 1
65
- @manager_thread.raise TryAgain
66
- end
67
-
68
- Signal.trap(:USR2) do
69
- @count -= 1
70
- @manager_thread.raise TryAgain
71
- end
72
-
73
- Signal.trap(ABORT_SIGNAL) do
74
- @abort_monitor = true
75
- @monitor_thread.raise Aborted if @monitor_thread && @monitor_thread.alive?
76
- end
77
-
78
- if @callback_queue
79
- Misc.purge_pipes(@queue.swrite, @queue.sread, @callback_queue.swrite)
80
- else
81
- Misc.purge_pipes(@queue.swrite, @queue.sread)
82
- end
83
-
84
- @total = 0
85
- @count = 0
86
-
87
- @manager_thread = Thread.new do
88
- while true
89
- break if processes_initiated && processes.empty? && (@monitor_thread && ! @monitor_thread.alive?)
90
- begin
91
- Thread.current["working"] = true
92
- if @close_up
93
- Thread.handle_interrupt(TryAgain => :never) do
94
- Log.debug "Closing up process queue #{Process.pid}"
95
- @count = 0
96
- @closing_thread = Thread.new do
97
- Thread.handle_interrupt(TryAgain => :never) do
98
- Log.debug "Pushing closed stream #{Process.pid}"
99
- while true
100
- @queue.push ClosedStream.new unless @queue.cleaned
101
- break if processes_initiated && processes.empty?
102
- end unless processes_initiated && processes.empty?
103
- end
104
- end
105
- @close_up = false
106
- end
107
- end
108
-
109
- begin
110
- sleep 3
111
- rescue TryAgain
112
- end
113
-
114
- raise TryAgain if @close_up
115
-
116
- process_mutex.synchronize do
117
- Thread.handle_interrupt(TryAgain => :never) do
118
- while @count > 0
119
- @count -= 1
120
- @total += 1
121
- processes << RbbtProcessQueueWorker.new(@queue, @callback_queue, @cleanup, @respawn, (@offset ? @total : false), &@init_block)
122
- Log.warn "Added process #{processes.last.pid} to #{Process.pid} (#{processes.length})"
123
- end
124
-
125
- while @count < 0
126
- @count += 1
127
- @total -= 1
128
- next unless processes.length > 1
129
- last = processes.reject{|p| p.stopping }.last
130
- last.stop
131
- Log.warn "Removed process #{last.pid} from #{Process.pid} (#{processes.length})"
132
- end
133
- end
134
- end
135
- rescue TryAgain
136
- retry
137
- rescue Aborted
138
- Log.low "Aborting manager thread #{Process.pid}"
139
- raise $!
140
- rescue Exception
141
- raise Exception
142
- end
143
- end
144
- Log.low "Manager thread stopped #{Process.pid}"
145
- end
146
-
147
- @callback_queue.close_read if @callback_queue
148
-
149
- num_processes.to_i.times do |i|
150
- @total += 1
151
- process_mutex.synchronize do
152
- processes << RbbtProcessQueueWorker.new(@queue, @callback_queue, @cleanup, @respawn, (@offset ? @total : false), &@init_block)
153
- end
154
- end
155
-
156
- processes_initiated = true
157
-
158
- @monitor_thread = Thread.new do
159
- begin
160
- while processes.any?
161
- raise Aborted if @abort_monitor
162
- #processes[0].join
163
- #Log.debug "Joined process #{processes[0].pid} of queue #{Process.pid}"
164
- #processes.shift
165
- pid, status = Process.wait2
166
- Log.debug "Joined process #{pid} of queue #{Process.pid} (status: #{status})"
167
- processes.reject!{|p| p.pid == pid}
168
- raise ProcessFailed.new pid if not status.success?
169
- end
170
- Log.low "All processes completed #{Process.pid}"
171
- rescue Aborted
172
- Log.exception $!
173
- Log.low "Aborting process monitor #{Process.pid}"
174
- processes.each{|p| p.abort_and_join}
175
- Log.low "Processes aborted #{Process.pid}"
176
- processes.clear
177
-
178
- @manager_thread.raise Aborted if @manager_thread.alive?
179
- raise Aborted, "Aborted monitor thread"
180
- rescue Exception
181
- Log.low "Process monitor exception [#{Process.pid}]: #{$!.message}"
182
- processes.each{|p| p.abort_and_join}
183
- Log.low "Processes aborted for monitor #{Process.pid}"
184
- processes.clear
185
-
186
- @manager_thread.report_on_exception = false
187
- @manager_thread.raise $! if @manager_thread.alive?
188
- raise Aborted, "Aborted monitor thread with exception"
189
- end
190
- end
191
- @monitor_thread.report_on_exception = false
192
-
193
- RbbtSemaphore.post_semaphore(@sem)
194
-
195
- Log.low "Process monitor #{Process.pid} joining threads"
196
- begin
197
- @monitor_thread.join
198
- @manager_thread.raise TryAgain if @manager_thread.alive?
199
- @manager_thread.join
200
- @callback_queue.push ClosedStream.new if @callback_queue
201
- rescue Exception
202
- Kernel.exit -1
203
- end
204
- Log.low "Process monitor #{Process.pid} threads joined successfully, now exit"
205
-
206
- Kernel.exit 0
207
- end
208
-
209
- @queue.close_read
210
- Log.info "Cpu process #{@master_pid} with #{num_processes} workers."
211
- Log.low "Signal #{@master_pid} USR1/USR2 (#10/#12) to increase/decrease workers."
212
- end
213
-
214
- def init(&block)
215
- @init_block = block
216
-
217
- init_master
218
-
219
- RbbtSemaphore.synchronize(@sem) do
220
- @callback_thread = Thread.new do
221
- begin
222
- loop do
223
- p = @callback_queue.pop unless @callback_queue.cleaned
224
-
225
- if Exception === p or (Array === p and Exception === p.first)
226
- e = Array === p ? p.first : p
227
- Log.low "Callback recieved exception from worker: #{e.message}" unless Aborted === e or ClosedStream === e
228
- raise e
229
- end
230
-
231
- if @callback.arity == 0
232
- @callback.call
233
- else
234
- @callback.call p
235
- end
236
- end
237
- rescue ClosedStream
238
- Log.low "Callback thread closing"
239
- rescue Aborted
240
- Log.low "Callback thread aborted"
241
- raise $!
242
- rescue Exception
243
- Log.low "Exception captured in callback: #{$!.message}"
244
- raise $!
245
- end
246
- end if @callback_queue
247
-
248
- @callback_thread.report_on_exception = false if @callback_thread
249
-
250
- end
251
-
252
- end
253
-
254
- def add_process
255
- Process.kill :USR1, @master_pid
256
- end
257
-
258
- def remove_process
259
- Process.kill :USR2, @master_pid
260
- end
261
-
262
- def _join
263
- error = :redo
264
- begin
265
- pid, @status = Process.waitpid2 @master_pid unless @status
266
- error = true unless @status.success?
267
- begin
268
- @callback_thread.join if @callback_thread
269
- raise ProcessFailed.new @master_pid unless @status.success?
270
- rescue
271
- exception = $!
272
- raise $!
273
- end
274
- error = false
275
- rescue Aborted, Interrupt
276
- exception = $!
277
- Log.exception $!
278
- error = true
279
- if @aborted
280
- raise $!
281
- else
282
- self.abort
283
- Log.high "Process queue #{@master_pid} aborted"
284
- retry
285
- end
286
- rescue Errno::ESRCH, Errno::ECHILD
287
- retry if Misc.pid_exists? @master_pid
288
- error = ! @status.success?
289
- ensure
290
- begin
291
- begin
292
- self.abort
293
- ensure
294
- _join
295
- end if error == :redo
296
-
297
- begin
298
- @callback_thread.join
299
- rescue Exception
300
- end
301
-
302
- Log.medium "Joining process queue #{"(error) " if error}#{@master_pid} #{@join}"
303
- begin
304
- if @join
305
- if @join.arity == 1
306
- @join.call(error)
307
- else
308
- @join.call
309
- end
310
- end
311
- end
312
- ensure
313
- self.clean
314
- end
315
-
316
- if exception
317
- raise exception
318
- else
319
- raise "Process queue #{@master_pid} failed"
320
- end if error
321
- end
322
- end
323
-
324
- def close_up_queue
325
- begin
326
- RbbtSemaphore.synchronize(@sem) do
327
- Process.kill CLOSE_SIGNAL, @master_pid
328
- end
329
- rescue Errno::ECHILD, Errno::ESRCH
330
- Log.debug "Cannot kill (CLOSE) #{@master_pid}: #{$!.message}"
331
- end if Misc.pid_exists? @master_pid
332
- end
333
-
334
- def join
335
- close_up_queue
336
-
337
- _join
338
- end
339
-
340
- def _abort
341
- begin
342
- Log.warn "Aborting process queue #{@master_pid}"
343
- Process.kill ABORT_SIGNAL, @master_pid
344
- rescue Errno::ECHILD, Errno::ESRCH
345
- Log.debug "Cannot abort #{@master_pid}: #{$!.message}"
346
- end
347
- end
348
-
349
- def abort
350
- _abort
351
- @callback_thread.raise(Aborted.new) if @callback_thread and @callback_thread.alive?
352
- @aborted = true
353
- begin
354
- _join
355
- rescue
356
- end
357
- end
358
-
359
- def clean
360
- RbbtSemaphore.delete_semaphore(@sem)
361
- begin
362
- self.abort if Misc.pid_exists?(@master_pid)
363
-
364
- ensure
365
- @queue.clean if @queue
366
- #@callback_thread.push ClosedStream if @callback_thread && @callback_thread.alive?
367
- @callback_queue.clean if @callback_queue
368
- end
369
- end
370
-
371
-
372
- def process(*e)
373
- begin
374
- @queue.push e
375
- rescue Errno::EPIPE
376
- raise Aborted
377
- end
378
- end
379
-
380
- def self.each(list, num = 3, &block)
381
- q = RbbtProcessQueue.new num
382
- q.init(&block)
383
- list.each do |elem| q.process elem end
384
- q.join
385
- end
386
- end
1
+ require 'rbbt/refactor'
2
+ Rbbt.require_instead 'scout/work_queue'
3
+ require_relative 'processes/refactor'
4
+ #require 'rbbt/util/concurrency/processes/worker'
5
+ #require 'rbbt/util/concurrency/processes/socket'
6
+ #
7
+ #class RbbtProcessQueue
8
+ #
9
+ # attr_accessor :num_processes, :queue, :process_monitor, :cleanup, :join, :reswpan, :offset
10
+ # def initialize(num_processes, cleanup = nil, join = nil, reswpan = nil, offset = false)
11
+ # @num_processes = num_processes
12
+ # @cleanup = cleanup
13
+ # @join = join
14
+ # @respawn = reswpan
15
+ # @offset = offset
16
+ # @queue = RbbtProcessSocket.new
17
+ #
18
+ # key = "/" << rand(1000000000).to_s << '.' << Process.pid.to_s;
19
+ # @sem = key + '.process'
20
+ # Log.debug "Creating process semaphore: #{@sem}"
21
+ # RbbtSemaphore.create_semaphore(@sem,1)
22
+ # end
23
+ #
24
+ #
25
+ # ABORT_SIGNAL = :INT
26
+ # CLOSE_SIGNAL = :PIPE
27
+ #
28
+ # attr_accessor :callback, :callback_queue, :callback_thread
29
+ # def callback(&block)
30
+ # if block_given?
31
+ #
32
+ # @callback = block
33
+ #
34
+ # @callback_queue = RbbtProcessSocket.new
35
+ #
36
+ # else
37
+ # @callback, @callback_queue, @callback_thread = nil, nil, nil
38
+ # end
39
+ # end
40
+ #
41
+ # def init_master
42
+ # RbbtSemaphore.wait_semaphore(@sem)
43
+ # @master_pid = Process.fork do
44
+ # @close_up = false
45
+ # processes_initiated = false
46
+ # processes = []
47
+ # process_mutex = Mutex.new
48
+ #
49
+ # Signal.trap(CLOSE_SIGNAL) do
50
+ # if ! @closing_thread
51
+ # @close_up = true
52
+ # Misc.insist([0,0.01,0.1,0.2,0.5]) do
53
+ # if ! @manager_thread
54
+ # Thread.pass
55
+ # raise "Manager thread for #{Process.pid} not found yet"
56
+ # end
57
+ #
58
+ # if @manager_thread.alive?
59
+ # raise "Manager thread for #{Process.pid} not working yet" unless @manager_thread["working"]
60
+ # @manager_thread.raise TryAgain
61
+ # end
62
+ # end
63
+ # end
64
+ # end
65
+ #
66
+ # Signal.trap(:USR1) do
67
+ # @count += 1
68
+ # @manager_thread.raise TryAgain
69
+ # end
70
+ #
71
+ # Signal.trap(:USR2) do
72
+ # @count -= 1
73
+ # @manager_thread.raise TryAgain
74
+ # end
75
+ #
76
+ # Signal.trap(ABORT_SIGNAL) do
77
+ # @abort_monitor = true
78
+ # @monitor_thread.raise Aborted if @monitor_thread && @monitor_thread.alive?
79
+ # end
80
+ #
81
+ # if @callback_queue
82
+ # Open.purge_pipes(@queue.swrite, @queue.sread, @callback_queue.swrite)
83
+ # else
84
+ # Open.purge_pipes(@queue.swrite, @queue.sread)
85
+ # end
86
+ #
87
+ # @total = 0
88
+ # @count = 0
89
+ #
90
+ # @manager_thread = Thread.new do
91
+ # while true
92
+ # break if processes_initiated && processes.empty? && (@monitor_thread && ! @monitor_thread.alive?)
93
+ # begin
94
+ # Thread.current["working"] = true
95
+ # if @close_up
96
+ # Thread.handle_interrupt(TryAgain => :never) do
97
+ # Log.debug "Closing up process queue #{Process.pid}"
98
+ # @count = 0
99
+ # @closing_thread = Thread.new do
100
+ # Thread.handle_interrupt(TryAgain => :never) do
101
+ # Log.debug "Pushing closed stream #{Process.pid}"
102
+ # while true
103
+ # @queue.push ClosedStream.new unless @queue.cleaned
104
+ # break if processes_initiated && processes.empty?
105
+ # end unless processes_initiated && processes.empty?
106
+ # end
107
+ # end
108
+ # @close_up = false
109
+ # end
110
+ # end
111
+ #
112
+ # begin
113
+ # sleep 3
114
+ # rescue TryAgain
115
+ # end
116
+ #
117
+ # raise TryAgain if @close_up
118
+ #
119
+ # process_mutex.synchronize do
120
+ # Thread.handle_interrupt(TryAgain => :never) do
121
+ # while @count > 0
122
+ # @count -= 1
123
+ # @total += 1
124
+ # processes << RbbtProcessQueueWorker.new(@queue, @callback_queue, @cleanup, @respawn, (@offset ? @total : false), &@init_block)
125
+ # Log.warn "Added process #{processes.last.pid} to #{Process.pid} (#{processes.length})"
126
+ # end
127
+ #
128
+ # while @count < 0
129
+ # @count += 1
130
+ # @total -= 1
131
+ # next unless processes.length > 1
132
+ # last = processes.reject{|p| p.stopping }.last
133
+ # last.stop
134
+ # Log.warn "Removed process #{last.pid} from #{Process.pid} (#{processes.length})"
135
+ # end
136
+ # end
137
+ # end
138
+ # rescue TryAgain
139
+ # retry
140
+ # rescue Aborted
141
+ # Log.low "Aborting manager thread #{Process.pid}"
142
+ # raise $!
143
+ # rescue Exception
144
+ # raise Exception
145
+ # end
146
+ # end
147
+ # Log.low "Manager thread stopped #{Process.pid}"
148
+ # end
149
+ #
150
+ # @callback_queue.close_read if @callback_queue
151
+ #
152
+ # num_processes.to_i.times do |i|
153
+ # @total += 1
154
+ # process_mutex.synchronize do
155
+ # processes << RbbtProcessQueueWorker.new(@queue, @callback_queue, @cleanup, @respawn, (@offset ? @total : false), &@init_block)
156
+ # end
157
+ # end
158
+ #
159
+ # processes_initiated = true
160
+ #
161
+ # @monitor_thread = Thread.new do
162
+ # begin
163
+ # while processes.any?
164
+ # raise Aborted if @abort_monitor
165
+ # #processes[0].join
166
+ # #Log.debug "Joined process #{processes[0].pid} of queue #{Process.pid}"
167
+ # #processes.shift
168
+ # pid, status = Process.wait2
169
+ # Log.debug "Joined process #{pid} of queue #{Process.pid} (status: #{status})"
170
+ # processes.reject!{|p| p.pid == pid}
171
+ # raise ProcessFailed.new pid if not status.success?
172
+ # end
173
+ # Log.low "All processes completed #{Process.pid}"
174
+ # rescue Aborted
175
+ # Log.exception $!
176
+ # Log.low "Aborting process monitor #{Process.pid}"
177
+ # processes.each{|p| p.abort_and_join}
178
+ # Log.low "Processes aborted #{Process.pid}"
179
+ # processes.clear
180
+ #
181
+ # @manager_thread.raise Aborted if @manager_thread.alive?
182
+ # raise Aborted, "Aborted monitor thread"
183
+ # rescue Exception
184
+ # Log.low "Process monitor exception [#{Process.pid}]: #{$!.message}"
185
+ # processes.each{|p| p.abort_and_join}
186
+ # Log.low "Processes aborted for monitor #{Process.pid}"
187
+ # processes.clear
188
+ #
189
+ # @manager_thread.report_on_exception = false
190
+ # @manager_thread.raise $! if @manager_thread.alive?
191
+ # raise Aborted, "Aborted monitor thread with exception"
192
+ # end
193
+ # end
194
+ # @monitor_thread.report_on_exception = false
195
+ #
196
+ # RbbtSemaphore.post_semaphore(@sem)
197
+ #
198
+ # Log.low "Process monitor #{Process.pid} joining threads"
199
+ # begin
200
+ # @monitor_thread.join
201
+ # @manager_thread.raise TryAgain if @manager_thread.alive?
202
+ # @manager_thread.join
203
+ # @callback_queue.push ClosedStream.new if @callback_queue
204
+ # rescue Exception
205
+ # Kernel.exit -1
206
+ # end
207
+ # Log.low "Process monitor #{Process.pid} threads joined successfully, now exit"
208
+ #
209
+ # Kernel.exit 0
210
+ # end
211
+ #
212
+ # @queue.close_read
213
+ # Log.info "Cpu process #{@master_pid} with #{num_processes} workers."
214
+ # Log.low "Signal #{@master_pid} USR1/USR2 (#10/#12) to increase/decrease workers."
215
+ # end
216
+ #
217
+ # def init(&block)
218
+ # @init_block = block
219
+ #
220
+ # init_master
221
+ #
222
+ # RbbtSemaphore.synchronize(@sem) do
223
+ # @callback_thread = Thread.new do
224
+ # begin
225
+ # loop do
226
+ # p = @callback_queue.pop unless @callback_queue.cleaned
227
+ #
228
+ # if Exception === p or (Array === p and Exception === p.first)
229
+ # e = Array === p ? p.first : p
230
+ # Log.low "Callback recieved exception from worker: #{e.message}" unless Aborted === e or ClosedStream === e
231
+ # raise e
232
+ # end
233
+ #
234
+ # if @callback.arity == 0
235
+ # @callback.call
236
+ # else
237
+ # @callback.call p
238
+ # end
239
+ # end
240
+ # rescue ClosedStream
241
+ # Log.low "Callback thread closing"
242
+ # rescue Aborted
243
+ # Log.low "Callback thread aborted"
244
+ # raise $!
245
+ # rescue Exception
246
+ # Log.low "Exception captured in callback: #{$!.message}"
247
+ # raise $!
248
+ # end
249
+ # end if @callback_queue
250
+ #
251
+ # @callback_thread.report_on_exception = false if @callback_thread
252
+ #
253
+ # end
254
+ #
255
+ # end
256
+ #
257
+ # def add_process
258
+ # Process.kill :USR1, @master_pid
259
+ # end
260
+ #
261
+ # def remove_process
262
+ # Process.kill :USR2, @master_pid
263
+ # end
264
+ #
265
+ # def _join
266
+ # error = :redo
267
+ # begin
268
+ # pid, @status = Process.waitpid2 @master_pid unless @status
269
+ # error = true unless @status.success?
270
+ # begin
271
+ # @callback_thread.join if @callback_thread
272
+ # raise ProcessFailed.new @master_pid unless @status.success?
273
+ # rescue
274
+ # exception = $!
275
+ # raise $!
276
+ # end
277
+ # error = false
278
+ # rescue Aborted, Interrupt
279
+ # exception = $!
280
+ # Log.exception $!
281
+ # error = true
282
+ # if @aborted
283
+ # raise $!
284
+ # else
285
+ # self.abort
286
+ # Log.high "Process queue #{@master_pid} aborted"
287
+ # retry
288
+ # end
289
+ # rescue Errno::ESRCH, Errno::ECHILD
290
+ # retry if Misc.pid_exists? @master_pid
291
+ # error = ! @status.success?
292
+ # ensure
293
+ # begin
294
+ # begin
295
+ # self.abort
296
+ # ensure
297
+ # _join
298
+ # end if error == :redo
299
+ #
300
+ # begin
301
+ # @callback_thread.join
302
+ # rescue Exception
303
+ # end
304
+ #
305
+ # Log.medium "Joining process queue #{"(error) " if error}#{@master_pid} #{@join}"
306
+ # begin
307
+ # if @join
308
+ # if @join.arity == 1
309
+ # @join.call(error)
310
+ # else
311
+ # @join.call
312
+ # end
313
+ # end
314
+ # end
315
+ # ensure
316
+ # self.clean
317
+ # end
318
+ #
319
+ # if exception
320
+ # raise exception
321
+ # else
322
+ # raise "Process queue #{@master_pid} failed"
323
+ # end if error
324
+ # end
325
+ # end
326
+ #
327
+ # def close_up_queue
328
+ # begin
329
+ # RbbtSemaphore.synchronize(@sem) do
330
+ # Process.kill CLOSE_SIGNAL, @master_pid
331
+ # end
332
+ # rescue Errno::ECHILD, Errno::ESRCH
333
+ # Log.debug "Cannot kill (CLOSE) #{@master_pid}: #{$!.message}"
334
+ # end if Misc.pid_exists? @master_pid
335
+ # end
336
+ #
337
+ # def join
338
+ # close_up_queue
339
+ #
340
+ # _join
341
+ # end
342
+ #
343
+ # def _abort
344
+ # begin
345
+ # Log.warn "Aborting process queue #{@master_pid}"
346
+ # Process.kill ABORT_SIGNAL, @master_pid
347
+ # rescue Errno::ECHILD, Errno::ESRCH
348
+ # Log.debug "Cannot abort #{@master_pid}: #{$!.message}"
349
+ # end
350
+ # end
351
+ #
352
+ # def abort
353
+ # _abort
354
+ # @callback_thread.raise(Aborted.new) if @callback_thread and @callback_thread.alive?
355
+ # @aborted = true
356
+ # begin
357
+ # _join
358
+ # rescue
359
+ # end
360
+ # end
361
+ #
362
+ # def clean
363
+ # RbbtSemaphore.delete_semaphore(@sem)
364
+ # begin
365
+ # self.abort if Misc.pid_exists?(@master_pid)
366
+ #
367
+ # ensure
368
+ # @queue.clean if @queue
369
+ # #@callback_thread.push ClosedStream if @callback_thread && @callback_thread.alive?
370
+ # @callback_queue.clean if @callback_queue
371
+ # end
372
+ # end
373
+ #
374
+ #
375
+ # def process(*e)
376
+ # begin
377
+ # @queue.push e
378
+ # rescue Errno::EPIPE
379
+ # raise Aborted
380
+ # end
381
+ # end
382
+ #
383
+ # def self.each(list, num = 3, &block)
384
+ # q = RbbtProcessQueue.new num
385
+ # q.init(&block)
386
+ # list.each do |elem| q.process elem end
387
+ # q.join
388
+ # end
389
+ #end