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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/bin/rbbt +67 -90
- data/bin/rbbt_exec.rb +2 -2
- data/etc/app.d/base.rb +2 -2
- data/etc/app.d/semaphores.rb +3 -3
- data/lib/rbbt/annotations/annotated_array.rb +207 -207
- data/lib/rbbt/annotations/refactor.rb +27 -0
- data/lib/rbbt/annotations/util.rb +282 -282
- data/lib/rbbt/annotations.rb +343 -320
- data/lib/rbbt/association/database.rb +200 -225
- data/lib/rbbt/association/index.rb +294 -291
- data/lib/rbbt/association/item.rb +227 -227
- data/lib/rbbt/association/open.rb +35 -34
- data/lib/rbbt/association/util.rb +0 -169
- data/lib/rbbt/association.rb +2 -4
- data/lib/rbbt/entity/identifiers.rb +119 -118
- data/lib/rbbt/entity/refactor.rb +12 -0
- data/lib/rbbt/entity.rb +319 -315
- data/lib/rbbt/hpc/batch.rb +72 -53
- data/lib/rbbt/hpc/lsf.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
- data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
- data/lib/rbbt/hpc/orchestrate.rb +19 -13
- data/lib/rbbt/hpc/slurm.rb +18 -18
- data/lib/rbbt/knowledge_base/entity.rb +13 -5
- data/lib/rbbt/knowledge_base/query.rb +2 -2
- data/lib/rbbt/knowledge_base/registry.rb +32 -31
- data/lib/rbbt/knowledge_base/traverse.rb +1 -1
- data/lib/rbbt/knowledge_base.rb +1 -1
- data/lib/rbbt/monitor.rb +36 -25
- data/lib/rbbt/persist/refactor.rb +166 -0
- data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
- data/lib/rbbt/persist/tsv.rb +187 -185
- data/lib/rbbt/persist.rb +556 -551
- data/lib/rbbt/refactor.rb +20 -0
- data/lib/rbbt/resource/path/refactor.rb +178 -0
- data/lib/rbbt/resource/path.rb +317 -497
- data/lib/rbbt/resource/util.rb +0 -48
- data/lib/rbbt/resource.rb +3 -390
- data/lib/rbbt/tsv/accessor.rb +2 -838
- data/lib/rbbt/tsv/attach.rb +303 -299
- data/lib/rbbt/tsv/change_id.rb +244 -245
- data/lib/rbbt/tsv/csv.rb +87 -85
- data/lib/rbbt/tsv/dumper.rb +2 -100
- data/lib/rbbt/tsv/excel.rb +26 -24
- data/lib/rbbt/tsv/field_index.rb +4 -1
- data/lib/rbbt/tsv/filter.rb +3 -2
- data/lib/rbbt/tsv/index.rb +2 -284
- data/lib/rbbt/tsv/manipulate.rb +750 -747
- data/lib/rbbt/tsv/marshal.rb +3 -3
- data/lib/rbbt/tsv/matrix.rb +2 -2
- data/lib/rbbt/tsv/parallel/through.rb +2 -1
- data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
- data/lib/rbbt/tsv/parser.rb +678 -678
- data/lib/rbbt/tsv/refactor.rb +195 -0
- data/lib/rbbt/tsv/stream.rb +253 -251
- data/lib/rbbt/tsv/util.rb +420 -420
- data/lib/rbbt/tsv.rb +210 -208
- data/lib/rbbt/util/R/eval.rb +4 -4
- data/lib/rbbt/util/R/plot.rb +62 -166
- data/lib/rbbt/util/R.rb +21 -18
- data/lib/rbbt/util/cmd.rb +2 -318
- data/lib/rbbt/util/color.rb +269 -269
- data/lib/rbbt/util/colorize.rb +89 -89
- data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
- data/lib/rbbt/util/concurrency/processes.rb +389 -386
- data/lib/rbbt/util/config.rb +169 -167
- data/lib/rbbt/util/filecache.rb +1 -1
- data/lib/rbbt/util/iruby.rb +20 -0
- data/lib/rbbt/util/log/progress/report.rb +241 -241
- data/lib/rbbt/util/log/progress/util.rb +99 -99
- data/lib/rbbt/util/log/progress.rb +102 -102
- data/lib/rbbt/util/log/refactor.rb +49 -0
- data/lib/rbbt/util/log.rb +486 -532
- data/lib/rbbt/util/migrate.rb +2 -2
- data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
- data/lib/rbbt/util/misc/development.rb +12 -11
- data/lib/rbbt/util/misc/exceptions.rb +117 -112
- data/lib/rbbt/util/misc/format.rb +2 -230
- data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
- data/lib/rbbt/util/misc/inspect.rb +2 -476
- data/lib/rbbt/util/misc/lock.rb +109 -106
- data/lib/rbbt/util/misc/omics.rb +9 -1
- data/lib/rbbt/util/misc/pipes.rb +765 -793
- data/lib/rbbt/util/misc/refactor.rb +20 -0
- data/lib/rbbt/util/misc/ssw.rb +27 -17
- data/lib/rbbt/util/misc/system.rb +92 -105
- data/lib/rbbt/util/misc.rb +39 -20
- data/lib/rbbt/util/named_array/refactor.rb +4 -0
- data/lib/rbbt/util/named_array.rb +3 -220
- data/lib/rbbt/util/open/refactor.rb +7 -0
- data/lib/rbbt/util/open.rb +3 -857
- data/lib/rbbt/util/procpath.rb +6 -6
- data/lib/rbbt/util/python/paths.rb +27 -0
- data/lib/rbbt/util/python/run.rb +115 -0
- data/lib/rbbt/util/python/script.rb +110 -0
- data/lib/rbbt/util/python/util.rb +3 -3
- data/lib/rbbt/util/python.rb +22 -81
- data/lib/rbbt/util/semaphore.rb +152 -148
- data/lib/rbbt/util/simpleopt.rb +9 -8
- data/lib/rbbt/util/ssh/refactor.rb +19 -0
- data/lib/rbbt/util/ssh.rb +122 -118
- data/lib/rbbt/util/tar.rb +117 -115
- data/lib/rbbt/util/tmpfile.rb +69 -67
- data/lib/rbbt/util/version.rb +2 -0
- data/lib/rbbt/workflow/refactor/entity.rb +11 -0
- data/lib/rbbt/workflow/refactor/export.rb +66 -0
- data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
- data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
- data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
- data/lib/rbbt/workflow/refactor.rb +150 -0
- data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
- data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
- data/lib/rbbt/workflow/remote_workflow.rb +6 -1
- data/lib/rbbt/workflow/step/run.rb +766 -766
- data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
- data/lib/rbbt/workflow/step.rb +2 -362
- data/lib/rbbt/workflow/task.rb +118 -118
- data/lib/rbbt/workflow/usage.rb +289 -287
- data/lib/rbbt/workflow/util/archive.rb +6 -5
- data/lib/rbbt/workflow/util/data.rb +1 -1
- data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
- data/lib/rbbt/workflow/util/trace.rb +79 -44
- data/lib/rbbt/workflow.rb +4 -882
- data/lib/rbbt-util.rb +21 -13
- data/lib/rbbt.rb +16 -3
- data/python/rbbt/__init__.py +96 -4
- data/python/rbbt/workflow/remote.py +104 -0
- data/python/rbbt/workflow.py +64 -0
- data/python/test.py +10 -0
- data/share/Rlib/plot.R +37 -37
- data/share/Rlib/svg.R +22 -5
- data/share/install/software/lib/install_helpers +1 -1
- data/share/rbbt_commands/hpc/list +2 -3
- data/share/rbbt_commands/hpc/orchestrate +4 -4
- data/share/rbbt_commands/hpc/tail +2 -0
- data/share/rbbt_commands/hpc/task +10 -7
- data/share/rbbt_commands/lsf/list +2 -3
- data/share/rbbt_commands/lsf/orchestrate +4 -4
- data/share/rbbt_commands/lsf/tail +2 -0
- data/share/rbbt_commands/lsf/task +10 -7
- data/share/rbbt_commands/migrate +1 -1
- data/share/rbbt_commands/pbs/list +2 -3
- data/share/rbbt_commands/pbs/orchestrate +4 -4
- data/share/rbbt_commands/pbs/tail +2 -0
- data/share/rbbt_commands/pbs/task +10 -7
- data/share/rbbt_commands/resource/produce +8 -1
- data/share/rbbt_commands/slurm/list +2 -3
- data/share/rbbt_commands/slurm/orchestrate +4 -4
- data/share/rbbt_commands/slurm/tail +2 -0
- data/share/rbbt_commands/slurm/task +10 -7
- data/share/rbbt_commands/system/clean +5 -5
- data/share/rbbt_commands/system/status +5 -5
- data/share/rbbt_commands/tsv/get +2 -3
- data/share/rbbt_commands/tsv/info +10 -13
- data/share/rbbt_commands/tsv/keys +18 -14
- data/share/rbbt_commands/tsv/slice +2 -2
- data/share/rbbt_commands/tsv/transpose +6 -2
- data/share/rbbt_commands/workflow/info +20 -24
- data/share/rbbt_commands/workflow/list +1 -1
- data/share/rbbt_commands/workflow/prov +20 -13
- data/share/rbbt_commands/workflow/retry +43 -0
- data/share/rbbt_commands/workflow/server +12 -2
- data/share/rbbt_commands/workflow/task +80 -73
- data/share/rbbt_commands/workflow/write_info +26 -9
- data/share/software/opt/ssw/ssw.c +861 -0
- data/share/software/opt/ssw/ssw.h +130 -0
- data/share/workflow_config.ru +3 -3
- metadata +45 -6
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -1,793 +1,765 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
ConcurrentStream.setup
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
rescue
|
109
|
-
Log.medium "
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
raise
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
#
|
132
|
-
#
|
133
|
-
|
134
|
-
#
|
135
|
-
#
|
136
|
-
|
137
|
-
#
|
138
|
-
#
|
139
|
-
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
|
144
|
-
#
|
145
|
-
#
|
146
|
-
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
#
|
155
|
-
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
|
171
|
-
#
|
172
|
-
#
|
173
|
-
|
174
|
-
#
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
rescue
|
202
|
-
Log.error("Tee stream #{i} #{Misc.fingerprint stream}
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
main_pipe
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
if
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
str
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
end
|
635
|
-
|
636
|
-
def self.
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
def self.
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
block.call line
|
767
|
-
end
|
768
|
-
rescue
|
769
|
-
Log.exception $!
|
770
|
-
monitor.raise $!
|
771
|
-
monitor.close unless monitor.closed?
|
772
|
-
monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
773
|
-
out.raise $! if out.respond_to?(:raise)
|
774
|
-
ensure
|
775
|
-
monitor.close unless monitor.closed?
|
776
|
-
monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
777
|
-
end
|
778
|
-
end
|
779
|
-
|
780
|
-
stream.annotate out if stream.respond_to? :annotate
|
781
|
-
ConcurrentStream.setup out, :threads => monitor_thread
|
782
|
-
end
|
783
|
-
|
784
|
-
def self.open_gz_pipe
|
785
|
-
sout = Misc.open_pipe do |sin|
|
786
|
-
yield sin
|
787
|
-
sin.close
|
788
|
-
end
|
789
|
-
|
790
|
-
Open.gzip(sout)
|
791
|
-
end
|
792
|
-
|
793
|
-
end
|
1
|
+
require_relative '../../refactor'
|
2
|
+
Rbbt.require_instead 'scout/open/stream'
|
3
|
+
|
4
|
+
#require 'rbbt'
|
5
|
+
#
|
6
|
+
#module Misc
|
7
|
+
# class << self
|
8
|
+
# attr_accessor :sensiblewrite_lock_dir
|
9
|
+
#
|
10
|
+
# def sensiblewrite_lock_dir
|
11
|
+
# @sensiblewrite_lock_dir ||= Rbbt.tmp.sensiblewrite_locks.find
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# class << self
|
16
|
+
# attr_accessor :sensiblewrite_dir
|
17
|
+
# def sensiblewrite_dir
|
18
|
+
# @sensiblewrite_dir = Rbbt.tmp.sensiblewrite.find
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# BLOCK_SIZE=1024 * 8
|
23
|
+
#
|
24
|
+
# SKIP_TAG="[SKIP TAG]"
|
25
|
+
#
|
26
|
+
# PIPE_MUTEX = Mutex.new
|
27
|
+
#
|
28
|
+
# OPEN_PIPE_IN = []
|
29
|
+
# def self.pipe
|
30
|
+
# OPEN_PIPE_IN.delete_if{|pipe| pipe.closed? }
|
31
|
+
# res = PIPE_MUTEX.synchronize do
|
32
|
+
# sout, sin = IO.pipe
|
33
|
+
# OPEN_PIPE_IN << sin
|
34
|
+
#
|
35
|
+
# [sout, sin]
|
36
|
+
# end
|
37
|
+
# Log.debug{"Creating pipe #{[res.last.inspect, res.first.inspect] * " => "}"}
|
38
|
+
# res
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# def self.with_fifo(path = nil, clean = true, &block)
|
42
|
+
# begin
|
43
|
+
# erase = path.nil?
|
44
|
+
# path = TmpFile.tmp_file if path.nil?
|
45
|
+
# File.rm path if clean && File.exist?(path)
|
46
|
+
# File.mkfifo path
|
47
|
+
# yield path
|
48
|
+
# ensure
|
49
|
+
# FileUtils.rm path if erase && File.exist?(path)
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# def self.release_pipes(*pipes)
|
54
|
+
# PIPE_MUTEX.synchronize do
|
55
|
+
# pipes.flatten.each do |pipe|
|
56
|
+
# pipe.close unless pipe.closed?
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# def self.purge_pipes(*save)
|
62
|
+
# PIPE_MUTEX.synchronize do
|
63
|
+
# OPEN_PIPE_IN.each do |pipe|
|
64
|
+
# next if save.include? pipe
|
65
|
+
# pipe.close unless pipe.closed?
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# def self.open_pipe(do_fork = false, close = true)
|
71
|
+
# raise "No block given" unless block_given?
|
72
|
+
#
|
73
|
+
# sout, sin = Misc.pipe
|
74
|
+
#
|
75
|
+
# if do_fork
|
76
|
+
#
|
77
|
+
# #parent_pid = Process.pid
|
78
|
+
# pid = Process.fork {
|
79
|
+
# purge_pipes(sin)
|
80
|
+
# sout.close
|
81
|
+
# begin
|
82
|
+
#
|
83
|
+
# yield sin
|
84
|
+
# sin.close if close and not sin.closed?
|
85
|
+
#
|
86
|
+
# rescue Exception
|
87
|
+
# Log.exception $!
|
88
|
+
# #Process.kill :INT, parent_pid
|
89
|
+
# Kernel.exit! -1
|
90
|
+
# end
|
91
|
+
# Kernel.exit! 0
|
92
|
+
# }
|
93
|
+
# sin.close
|
94
|
+
#
|
95
|
+
# ConcurrentStream.setup sout, :pids => [pid]
|
96
|
+
# else
|
97
|
+
#
|
98
|
+
# ConcurrentStream.setup sin, :pair => sout
|
99
|
+
# ConcurrentStream.setup sout, :pair => sin
|
100
|
+
#
|
101
|
+
# thread = Thread.new do
|
102
|
+
# begin
|
103
|
+
#
|
104
|
+
# yield sin
|
105
|
+
#
|
106
|
+
# sin.close if close and not sin.closed? and not sin.aborted?
|
107
|
+
#
|
108
|
+
# rescue Aborted
|
109
|
+
# Log.medium "Aborted open_pipe: #{$!.message}"
|
110
|
+
# raise $!
|
111
|
+
# rescue Exception
|
112
|
+
# Log.medium "Exception in open_pipe: #{$!.message}"
|
113
|
+
# Log.exception $!
|
114
|
+
# begin
|
115
|
+
# sin.raise($!) if sin.respond_to? :raise
|
116
|
+
# sin.join if sin.respond_to? :join
|
117
|
+
# ensure
|
118
|
+
# raise $!
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# sin.threads = [thread]
|
124
|
+
# sout.threads = [thread]
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# sout
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# #def self.tee_stream_thread(stream)
|
131
|
+
# # stream_out1, stream_in1 = Misc.pipe
|
132
|
+
# # stream_out2, stream_in2 = Misc.pipe
|
133
|
+
#
|
134
|
+
# # splitter_thread = Thread.new(Thread.current) do |parent|
|
135
|
+
# # begin
|
136
|
+
#
|
137
|
+
# # skip1 = skip2 = false
|
138
|
+
# # while block = stream.read(1024)
|
139
|
+
#
|
140
|
+
# # begin
|
141
|
+
# # stream_in1.write block;
|
142
|
+
# # rescue IOError
|
143
|
+
# # Log.medium("Tee stream 1 #{Misc.fingerprint stream} IOError: #{$!.message}");
|
144
|
+
# # skip1 = true
|
145
|
+
# # end unless skip1
|
146
|
+
#
|
147
|
+
# # begin
|
148
|
+
# # stream_in2.write block
|
149
|
+
# # rescue IOError
|
150
|
+
# # Log.medium("Tee stream 2 #{Misc.fingerprint stream} IOError: #{$!.message}");
|
151
|
+
# # skip2 = true
|
152
|
+
# # end unless skip2
|
153
|
+
#
|
154
|
+
# # end
|
155
|
+
#
|
156
|
+
# # stream_in1.close unless stream_in1.closed?
|
157
|
+
# # stream.join if stream.respond_to? :join
|
158
|
+
# # stream_in2.close unless stream_in2.closed?
|
159
|
+
# # rescue Aborted, Interrupt
|
160
|
+
# # stream_out1.abort if stream_out1.respond_to? :abort
|
161
|
+
# # stream.abort if stream.respond_to? :abort
|
162
|
+
# # stream_out2.abort if stream_out2.respond_to? :abort
|
163
|
+
# # Log.medium "Tee aborting #{Misc.fingerprint stream}"
|
164
|
+
# # raise $!
|
165
|
+
# # rescue Exception
|
166
|
+
# # stream_out1.abort if stream_out1.respond_to? :abort
|
167
|
+
# # stream.abort if stream.respond_to? :abort
|
168
|
+
# # stream_out2.abort if stream_out2.respond_to? :abort
|
169
|
+
# # Log.medium "Tee exception #{Misc.fingerprint stream}"
|
170
|
+
# # raise $!
|
171
|
+
# # end
|
172
|
+
# # end
|
173
|
+
#
|
174
|
+
# # ConcurrentStream.setup stream_out1, :threads => splitter_thread
|
175
|
+
# # ConcurrentStream.setup stream_out2, :threads => splitter_thread
|
176
|
+
#
|
177
|
+
# # [stream_out1, stream_out2]
|
178
|
+
# #end
|
179
|
+
#
|
180
|
+
# def self.tee_stream_thread_multiple(stream, num = 2)
|
181
|
+
# in_pipes = []
|
182
|
+
# out_pipes = []
|
183
|
+
# num.times do
|
184
|
+
# sout, sin = Misc.pipe
|
185
|
+
# in_pipes << sin
|
186
|
+
# out_pipes << sout
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# filename = stream.filename if stream.respond_to? :filename
|
190
|
+
#
|
191
|
+
# splitter_thread = Thread.new(Thread.current) do |parent|
|
192
|
+
# begin
|
193
|
+
#
|
194
|
+
# skip = [false] * num
|
195
|
+
# begin
|
196
|
+
# while block = stream.readpartial(BLOCK_SIZE)
|
197
|
+
#
|
198
|
+
# in_pipes.each_with_index do |sin,i|
|
199
|
+
# begin
|
200
|
+
# sin.write block
|
201
|
+
# rescue IOError
|
202
|
+
# Log.error("Tee stream #{i} #{Misc.fingerprint stream} IOError: #{$!.message} (#{Misc.fingerprint sin})");
|
203
|
+
# skip[i] = true
|
204
|
+
# rescue
|
205
|
+
# Log.error("Tee stream #{i} #{Misc.fingerprint stream} Exception: #{$!.message} (#{Misc.fingerprint sin})");
|
206
|
+
# raise $!
|
207
|
+
# end unless skip[i]
|
208
|
+
# end
|
209
|
+
# end
|
210
|
+
# rescue IOError
|
211
|
+
# end
|
212
|
+
#
|
213
|
+
# stream.close unless stream.closed?
|
214
|
+
# #stream.join if stream.respond_to? :join
|
215
|
+
# in_pipes.first.close unless in_pipes.first.closed?
|
216
|
+
# #Log.medium "Tee done #{Misc.fingerprint stream}"
|
217
|
+
# rescue Aborted, Interrupt
|
218
|
+
# stream.abort if stream.respond_to? :abort
|
219
|
+
# out_pipes.each do |sout|
|
220
|
+
# sout.abort if sout.respond_to? :abort
|
221
|
+
# end
|
222
|
+
# Log.medium "Tee aborting #{Misc.fingerprint stream}"
|
223
|
+
# raise $!
|
224
|
+
# rescue Exception
|
225
|
+
# stream.abort($!) if stream.respond_to? :abort
|
226
|
+
# out_pipes.each do |sout|
|
227
|
+
# sout.abort if sout.respond_to? :abort
|
228
|
+
# end
|
229
|
+
# Log.medium "Tee exception #{Misc.fingerprint stream}"
|
230
|
+
# raise $!
|
231
|
+
# end
|
232
|
+
# end
|
233
|
+
#
|
234
|
+
# out_pipes.each do |sout|
|
235
|
+
# ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename, :_pair => stream
|
236
|
+
# end
|
237
|
+
#
|
238
|
+
# main_pipe = out_pipes.first
|
239
|
+
# main_pipe.autojoin = true
|
240
|
+
#
|
241
|
+
# main_pipe.callback = Proc.new do
|
242
|
+
# stream.join if stream.respond_to? :join
|
243
|
+
# in_pipes[1..-1].each do |sin|
|
244
|
+
# sin.close unless sin.closed?
|
245
|
+
# end
|
246
|
+
# end
|
247
|
+
#
|
248
|
+
# out_pipes
|
249
|
+
# end
|
250
|
+
#
|
251
|
+
# def self.tee_stream_thread(stream)
|
252
|
+
# tee_stream_thread_multiple(stream, 2)
|
253
|
+
# end
|
254
|
+
#
|
255
|
+
# def self.dup_stream_multiple(stream, num = 1)
|
256
|
+
# stream_dup = stream.dup
|
257
|
+
# if stream.respond_to? :annotate
|
258
|
+
# stream.annotate stream_dup
|
259
|
+
# stream.clear
|
260
|
+
# end
|
261
|
+
# tee1, *rest = Misc.tee_stream stream_dup, num + 1
|
262
|
+
# stream.reopen(tee1)
|
263
|
+
#
|
264
|
+
# #ToDo: I can't explain why the @threads variable appears with the value of
|
265
|
+
# # @filename
|
266
|
+
# stream.instance_variable_set(:@threads, nil) if stream.instance_variables.include?(:@threads)
|
267
|
+
#
|
268
|
+
# tee1.annotate(stream)
|
269
|
+
# rest
|
270
|
+
# end
|
271
|
+
#
|
272
|
+
# def self.dup_stream(stream)
|
273
|
+
# dup_stream_multiple(stream, 1).first
|
274
|
+
# end
|
275
|
+
#
|
276
|
+
# class << self
|
277
|
+
# alias tee_stream tee_stream_thread_multiple
|
278
|
+
# end
|
279
|
+
#
|
280
|
+
# def self.read_full_stream(io)
|
281
|
+
# str = ""
|
282
|
+
# begin
|
283
|
+
# while block = io.read(BLOCK_SIZE)
|
284
|
+
# str << block
|
285
|
+
# end
|
286
|
+
# io.join if io.respond_to? :join
|
287
|
+
# rescue
|
288
|
+
# io.abort if io.respond_to? :abort
|
289
|
+
# end
|
290
|
+
# str
|
291
|
+
# end
|
292
|
+
#
|
293
|
+
# def self.consume_stream(io, in_thread = false, into = nil, into_close = true, &block)
|
294
|
+
# return if Path === io
|
295
|
+
# return unless io.respond_to? :read
|
296
|
+
#
|
297
|
+
# if io.respond_to? :closed? and io.closed?
|
298
|
+
# io.join if io.respond_to? :join
|
299
|
+
# return
|
300
|
+
# end
|
301
|
+
#
|
302
|
+
# if in_thread
|
303
|
+
# Thread.new(Thread.current) do |parent|
|
304
|
+
# begin
|
305
|
+
# consume_stream(io, false, into, into_close)
|
306
|
+
# rescue Exception
|
307
|
+
# parent.raise $!
|
308
|
+
# end
|
309
|
+
# end
|
310
|
+
# else
|
311
|
+
# if into
|
312
|
+
# Log.medium "Consuming stream #{Misc.fingerprint io} -> #{Misc.fingerprint into}"
|
313
|
+
# else
|
314
|
+
# Log.medium "Consuming stream #{Misc.fingerprint io}"
|
315
|
+
# end
|
316
|
+
#
|
317
|
+
# begin
|
318
|
+
# into = into.find if Path === into
|
319
|
+
# if String === into
|
320
|
+
# dir = File.dirname(into)
|
321
|
+
# Open.mkdir dir unless Open.exists?(dir)
|
322
|
+
# into_path, into = into, Open.open(into, :mode => 'w')
|
323
|
+
# end
|
324
|
+
# into.sync = true if IO === into
|
325
|
+
# into_close = false unless into.respond_to? :close
|
326
|
+
# io.sync = true
|
327
|
+
#
|
328
|
+
# begin
|
329
|
+
# while c = io.readpartial(BLOCK_SIZE)
|
330
|
+
# into << c if into
|
331
|
+
# end
|
332
|
+
# rescue EOFError
|
333
|
+
# end
|
334
|
+
#
|
335
|
+
# io.join if io.respond_to? :join
|
336
|
+
# io.close unless io.closed?
|
337
|
+
# into.close if into and into_close and not into.closed?
|
338
|
+
# into.join if into and into_close and into.respond_to?(:joined?) and not into.joined?
|
339
|
+
# block.call if block_given?
|
340
|
+
#
|
341
|
+
# #Log.medium "Done consuming stream #{Misc.fingerprint io}"
|
342
|
+
# rescue Aborted
|
343
|
+
# Log.medium "Consume stream aborted #{Misc.fingerprint io}"
|
344
|
+
# io.abort if io.respond_to? :abort
|
345
|
+
# #io.close unless io.closed?
|
346
|
+
# FileUtils.rm into_path if into_path and File.exist? into_path
|
347
|
+
# rescue Exception
|
348
|
+
# Log.medium "Exception consuming stream: #{Misc.fingerprint io}: #{$!.message}"
|
349
|
+
# io.abort $! if io.respond_to? :abort
|
350
|
+
# FileUtils.rm into_path if into_path and File.exist? into_path
|
351
|
+
# raise $!
|
352
|
+
# end
|
353
|
+
# end
|
354
|
+
# end
|
355
|
+
#
|
356
|
+
# def self.read_stream(stream, size)
|
357
|
+
# str = nil
|
358
|
+
# Thread.pass while IO.select([stream],nil,nil,1).nil?
|
359
|
+
# while not str = stream.read(size)
|
360
|
+
# IO.select([stream],nil,nil,1)
|
361
|
+
# Thread.pass
|
362
|
+
# raise ClosedStream if stream.eof?
|
363
|
+
# end
|
364
|
+
#
|
365
|
+
# while str.length < size
|
366
|
+
# raise ClosedStream if stream.eof?
|
367
|
+
# IO.select([stream],nil,nil,1)
|
368
|
+
# if new = stream.read(size-str.length)
|
369
|
+
# str << new
|
370
|
+
# end
|
371
|
+
# end
|
372
|
+
# str
|
373
|
+
# end
|
374
|
+
#
|
375
|
+
# def self.sensiblewrite(*args, &block)
|
376
|
+
# Open.sensible_write(*args, &block)
|
377
|
+
# end
|
378
|
+
#
|
379
|
+
# #def self.sensiblewrite(path, content = nil, options = {}, &block)
|
380
|
+
# # force = Misc.process_options options, :force
|
381
|
+
#
|
382
|
+
# # if Open.exists? path and not force
|
383
|
+
# # Misc.consume_stream content
|
384
|
+
# # return
|
385
|
+
# # end
|
386
|
+
#
|
387
|
+
# # lock_options = Misc.pull_keys options.dup, :lock
|
388
|
+
# # lock_options = lock_options[:lock] if Hash === lock_options[:lock]
|
389
|
+
# # tmp_path = Persist.persistence_path(path, {:dir => Misc.sensiblewrite_dir})
|
390
|
+
# # tmp_path_lock = Persist.persistence_path(path, {:dir => Misc.sensiblewrite_lock_dir})
|
391
|
+
#
|
392
|
+
# # tmp_path_lock = nil if FalseClass === options[:lock]
|
393
|
+
#
|
394
|
+
# # Misc.lock tmp_path_lock, lock_options do
|
395
|
+
#
|
396
|
+
# # if Open.exists? path and not force
|
397
|
+
# # Log.warn "Path exists in sensiblewrite, not forcing update: #{ path }"
|
398
|
+
# # Misc.consume_stream content
|
399
|
+
# # else
|
400
|
+
# # FileUtils.mkdir_p File.dirname(tmp_path) unless File.directory? File.dirname(tmp_path)
|
401
|
+
# # FileUtils.rm_f tmp_path if File.exist? tmp_path
|
402
|
+
# # begin
|
403
|
+
#
|
404
|
+
# # case
|
405
|
+
# # when block_given?
|
406
|
+
# # File.open(tmp_path, 'wb', &block)
|
407
|
+
# # when String === content
|
408
|
+
# # File.open(tmp_path, 'wb') do |f| f.write content end
|
409
|
+
# # when (IO === content or StringIO === content or File === content)
|
410
|
+
#
|
411
|
+
# # Open.write(tmp_path) do |f|
|
412
|
+
# # f.sync = true
|
413
|
+
# # while block = content.read(BLOCK_SIZE)
|
414
|
+
# # f.write block
|
415
|
+
# # end
|
416
|
+
# # end
|
417
|
+
# # else
|
418
|
+
# # File.open(tmp_path, 'wb') do |f| end
|
419
|
+
# # end
|
420
|
+
#
|
421
|
+
# # begin
|
422
|
+
# # Misc.insist do
|
423
|
+
# # Open.mv tmp_path, path, lock_options
|
424
|
+
# # end
|
425
|
+
# # rescue Exception
|
426
|
+
# # raise $! unless Open.exists? path
|
427
|
+
# # end
|
428
|
+
#
|
429
|
+
# # Open.touch path if Open.exists? path
|
430
|
+
# # content.join if content.respond_to?(:join) and not Path === content and not (content.respond_to?(:joined?) && content.joined?)
|
431
|
+
#
|
432
|
+
# # Open.notify_write(path)
|
433
|
+
# # rescue Aborted
|
434
|
+
# # Log.medium "Aborted sensiblewrite -- #{ Log.reset << Log.color(:blue, path) }"
|
435
|
+
# # content.abort if content.respond_to? :abort
|
436
|
+
# # Open.rm path if File.exist? path
|
437
|
+
# # rescue Exception
|
438
|
+
# # exception = (AbortedStream === content and content.exception) ? content.exception : $!
|
439
|
+
# # Log.medium "Exception in sensiblewrite: [#{Process.pid}] #{exception.message} -- #{ Log.color :blue, path }"
|
440
|
+
# # content.abort if content.respond_to? :abort
|
441
|
+
# # Open.rm path if File.exist? path
|
442
|
+
# # raise exception
|
443
|
+
# # rescue
|
444
|
+
# # Log.exception $!
|
445
|
+
# # raise $!
|
446
|
+
# # ensure
|
447
|
+
# # FileUtils.rm_f tmp_path if File.exist? tmp_path
|
448
|
+
# # if Lockfile === lock_options[:lock] and lock_options[:lock].locked?
|
449
|
+
# # lock_options[:lock].unlock
|
450
|
+
# # end
|
451
|
+
# # end
|
452
|
+
# # end
|
453
|
+
# # end
|
454
|
+
# #end
|
455
|
+
#
|
456
|
+
# def self.process_stream(s)
|
457
|
+
# begin
|
458
|
+
# yield s
|
459
|
+
# s.join if s.respond_to? :join
|
460
|
+
# rescue
|
461
|
+
# s.abort if s.respond_to? :abort
|
462
|
+
# raise $!
|
463
|
+
# end
|
464
|
+
# end
|
465
|
+
#
|
466
|
+
# def self.collapse_stream(s, line = nil, sep = "\t", header = nil, &block)
|
467
|
+
# sep ||= "\t"
|
468
|
+
# Misc.open_pipe do |sin|
|
469
|
+
# sin.puts header if header
|
470
|
+
# process_stream(s) do |s|
|
471
|
+
# line ||= s.gets
|
472
|
+
#
|
473
|
+
# current_parts = []
|
474
|
+
# while line
|
475
|
+
# key, *parts = line.chomp.split(sep, -1)
|
476
|
+
# case
|
477
|
+
# when key.nil?
|
478
|
+
# when current_parts.nil?
|
479
|
+
# current_parts = parts
|
480
|
+
# current_key = key
|
481
|
+
# when current_key == key
|
482
|
+
# parts.each_with_index do |part,i|
|
483
|
+
# if current_parts[i].nil?
|
484
|
+
# current_parts[i] = "|" << part
|
485
|
+
# else
|
486
|
+
# current_parts[i] = current_parts[i] << "|" << part
|
487
|
+
# end
|
488
|
+
# end
|
489
|
+
#
|
490
|
+
# (parts.length..current_parts.length-1).to_a.each do |pos|
|
491
|
+
# current_parts[pos] = current_parts[pos] << "|" << ""
|
492
|
+
# end
|
493
|
+
# when current_key.nil?
|
494
|
+
# current_key = key
|
495
|
+
# current_parts = parts
|
496
|
+
# when current_key != key
|
497
|
+
# if block_given?
|
498
|
+
# res = block.call(current_parts)
|
499
|
+
# sin.puts [current_key, res] * sep
|
500
|
+
# else
|
501
|
+
# sin.puts [current_key, current_parts].flatten * sep
|
502
|
+
# end
|
503
|
+
# current_key = key
|
504
|
+
# current_parts = parts
|
505
|
+
# end
|
506
|
+
# line = s.gets
|
507
|
+
# end
|
508
|
+
#
|
509
|
+
# if block_given?
|
510
|
+
# res = block.call(current_parts)
|
511
|
+
# sin.puts [current_key, res] * sep
|
512
|
+
# else
|
513
|
+
# sin.puts [current_key, current_parts].flatten * sep
|
514
|
+
# end unless current_key.nil?
|
515
|
+
# end
|
516
|
+
# end
|
517
|
+
# end
|
518
|
+
#
|
519
|
+
# def self.buffer_stream(stream)
|
520
|
+
# sout, sin = Misc.pipe
|
521
|
+
# Misc.consume_stream(stream, true, sin)
|
522
|
+
# sout
|
523
|
+
# end
|
524
|
+
#
|
525
|
+
# def self._paste_streams(streams, output, lines = nil, sep = "\t", header = nil, &block)
|
526
|
+
# output.puts header if header
|
527
|
+
# streams = streams.collect do |stream|
|
528
|
+
# if defined? Step and Step === stream
|
529
|
+
# io = stream.get_stream
|
530
|
+
# if io
|
531
|
+
# buffer_stream(io)
|
532
|
+
# else
|
533
|
+
# stream.join.path.open
|
534
|
+
# end
|
535
|
+
# else
|
536
|
+
# stream
|
537
|
+
# end
|
538
|
+
# end
|
539
|
+
#
|
540
|
+
# begin
|
541
|
+
#
|
542
|
+
# lines ||= streams.collect{|s| s.gets }
|
543
|
+
# keys = []
|
544
|
+
# parts = []
|
545
|
+
# lines.each_with_index do |line,i|
|
546
|
+
# if line.nil?
|
547
|
+
# keys[i] = nil
|
548
|
+
# parts[i] = []
|
549
|
+
# else
|
550
|
+
# key, *p = line.chomp.split(sep, -1)
|
551
|
+
# keys[i] = key
|
552
|
+
# parts[i] = p
|
553
|
+
# end
|
554
|
+
# end
|
555
|
+
# sizes = parts.collect{|p| p.nil? ? 0 : p.length }
|
556
|
+
# last_min = nil
|
557
|
+
#
|
558
|
+
# while lines.compact.any?
|
559
|
+
# if block_given?
|
560
|
+
# min = keys.compact.sort(&block).first
|
561
|
+
# else
|
562
|
+
# min = keys.compact.sort.first
|
563
|
+
# end
|
564
|
+
# str = []
|
565
|
+
# threads = []
|
566
|
+
# keys.each_with_index do |key,i|
|
567
|
+
# case key
|
568
|
+
# when min
|
569
|
+
# if parts[i] == [SKIP_TAG]
|
570
|
+
# str << [sep * (sizes[i]-1)] if sizes[i] > 0
|
571
|
+
# else
|
572
|
+
# str << [parts[i] * sep]
|
573
|
+
# end
|
574
|
+
#
|
575
|
+
# line = lines[i] = streams[i].gets
|
576
|
+
#
|
577
|
+
# if line.nil?
|
578
|
+
# keys[i] = nil
|
579
|
+
# parts[i] = nil
|
580
|
+
# streams[i].close unless streams[i].closed?
|
581
|
+
# streams[i].join if streams[i].respond_to?(:join)
|
582
|
+
# else
|
583
|
+
# k, *p = line.chomp.split(sep, -1)
|
584
|
+
# keys[i] = k
|
585
|
+
# parts[i] = p
|
586
|
+
# end
|
587
|
+
# else
|
588
|
+
# str << [sep * (sizes[i]-1)] if sizes[i] > 0
|
589
|
+
# end
|
590
|
+
# end
|
591
|
+
#
|
592
|
+
# output.puts [min, str.flatten*sep] * sep
|
593
|
+
# end
|
594
|
+
#
|
595
|
+
# streams.each do |stream|
|
596
|
+
# stream.close unless stream.closed?
|
597
|
+
# stream.join if stream.respond_to?(:join)
|
598
|
+
# end
|
599
|
+
# rescue
|
600
|
+
# Log.exception $!
|
601
|
+
# streams.each do |stream|
|
602
|
+
# stream.abort if stream.respond_to? :abort
|
603
|
+
# end
|
604
|
+
# raise $!
|
605
|
+
# end
|
606
|
+
# end
|
607
|
+
#
|
608
|
+
# def self.paste_streams(streams, lines = nil, sep = "\t", header = nil, &block)
|
609
|
+
# sep ||= "\t"
|
610
|
+
# num_streams = streams.length
|
611
|
+
# Misc.open_pipe do |sin|
|
612
|
+
# self._paste_streams(streams, sin, lines, sep, header, &block)
|
613
|
+
# end
|
614
|
+
# end
|
615
|
+
#
|
616
|
+
# def self.save_stream(file, stream)
|
617
|
+
# save, out = Misc.tee_stream stream
|
618
|
+
# out.filename = file
|
619
|
+
# save.filename = file
|
620
|
+
#
|
621
|
+
# Thread.new(Thread.current) do |parent|
|
622
|
+
# begin
|
623
|
+
# Misc.sensiblewrite(file, save)
|
624
|
+
# rescue Exception
|
625
|
+
# save.abort if save.respond_to? :abort
|
626
|
+
# stream.abort if stream.respond_to? :abort
|
627
|
+
# stream.join
|
628
|
+
# Log.medium "Exception in save_stream: #{$!.message}"
|
629
|
+
# raise $!
|
630
|
+
# end
|
631
|
+
# end
|
632
|
+
#
|
633
|
+
# out
|
634
|
+
# end
|
635
|
+
#
|
636
|
+
# def self.intercalate_streams(streams)
|
637
|
+
# Misc.open_pipe do |sin|
|
638
|
+
# continue = true
|
639
|
+
# while continue
|
640
|
+
# lines = streams.collect{|stream| stream.eof? ? nil : stream.gets }.compact
|
641
|
+
# lines.each do |line|
|
642
|
+
# sin.puts line
|
643
|
+
# end
|
644
|
+
# continue = false if lines.empty?
|
645
|
+
# end
|
646
|
+
# streams.each do |stream|
|
647
|
+
# stream.join if stream.respond_to? :join
|
648
|
+
# stream.close if stream.respond_to? :close and not stream.closed?
|
649
|
+
# end
|
650
|
+
# end
|
651
|
+
# end
|
652
|
+
#
|
653
|
+
# def self.compare_lines(stream1, stream2, args, sort = false)
|
654
|
+
# if sort
|
655
|
+
# stream1 = Misc.sort_stream stream1
|
656
|
+
# stream2 = Misc.sort_stream stream2
|
657
|
+
# compare_lines(stream1, stream2, args, false)
|
658
|
+
# else
|
659
|
+
# erase = []
|
660
|
+
#
|
661
|
+
# if Path === stream1 or (String === stream1 and File.exist? stream1)
|
662
|
+
# file1 = stream1
|
663
|
+
# else
|
664
|
+
# file1 = TmpFile.tmp_file
|
665
|
+
# erase << file1
|
666
|
+
# Misc.consume_stream(TSV.get_stream(stream1), false, file1)
|
667
|
+
# end
|
668
|
+
#
|
669
|
+
# if Path === stream2 or (String === stream2 and File.exist? stream2)
|
670
|
+
# file2 = stream2
|
671
|
+
# else
|
672
|
+
# file2 = TmpFile.tmp_file
|
673
|
+
# erase << file2
|
674
|
+
# Misc.consume_stream(TSV.get_stream(stream2), false, file2)
|
675
|
+
# end
|
676
|
+
#
|
677
|
+
# CMD.cmd("env LC_ALL=C comm #{args} '#{file1}' '#{file2}'", :pipe => true, :post => Proc.new{ erase.each{|f| FileUtils.rm f } })
|
678
|
+
# end
|
679
|
+
# end
|
680
|
+
#
|
681
|
+
# def self.remove_lines(stream1, stream2, sort)
|
682
|
+
# self.compare_lines(stream1, stream2, '-2 -3', sort)
|
683
|
+
# end
|
684
|
+
#
|
685
|
+
# def self.select_lines(stream1, stream2, sort)
|
686
|
+
# self.compare_lines(stream1, stream2, '-1 -2', sort)
|
687
|
+
# end
|
688
|
+
#
|
689
|
+
#
|
690
|
+
# def self.add_stream_filename(io, filename)
|
691
|
+
# if ! io.respond_to? :filename
|
692
|
+
# class << io
|
693
|
+
# attr_accessor :filename
|
694
|
+
# end
|
695
|
+
# io.filename = filename
|
696
|
+
# end
|
697
|
+
# end
|
698
|
+
#
|
699
|
+
# def self.sort_mutation_stream_strict(stream, sep=":")
|
700
|
+
# CMD.cmd("grep '#{sep}' | sort -u | sed 's/^M:/MT:/' | env LC_ALL=C sort -V -k1,1 -k2,2n -k3,3n -t'#{sep}'", :in => stream, :pipe => true, :no_fail => true)
|
701
|
+
# end
|
702
|
+
#
|
703
|
+
# def self.sort_mutation_stream(stream, sep=":")
|
704
|
+
# CMD.cmd("grep '#{sep}' | sort -u | sed 's/^M:/MT:/' | env LC_ALL=C sort -k1,1 -k2,2n -k3,3n -t'#{sep}'", :in => stream, :pipe => true, :no_fail => true)
|
705
|
+
# end
|
706
|
+
#
|
707
|
+
# def self.swap_quoted_character(stream, charout="\n", charin=" ", quote='"')
|
708
|
+
# io = Misc.open_pipe do |sin|
|
709
|
+
# begin
|
710
|
+
# quoted = false
|
711
|
+
# prev = nil
|
712
|
+
# while c = stream.getc
|
713
|
+
# if c == quote and not prev == "\\"
|
714
|
+
# quoted = ! quoted
|
715
|
+
# end
|
716
|
+
# c = charin if c == charout and quoted
|
717
|
+
# sin << c
|
718
|
+
# prev = c
|
719
|
+
# end
|
720
|
+
# rescue
|
721
|
+
# stream.abort if stream.respond_to? :abort
|
722
|
+
# raise $!
|
723
|
+
# ensure
|
724
|
+
# stream.join if stream.respond_to? :join
|
725
|
+
# end
|
726
|
+
# end
|
727
|
+
# end
|
728
|
+
#
|
729
|
+
# def self.remove_quoted_new_line(stream, quote = '"')
|
730
|
+
# swap_quoted_character(stream, "\n", " ", quote)
|
731
|
+
# end
|
732
|
+
#
|
733
|
+
# def self.line_monitor_stream(stream, &block)
|
734
|
+
# monitor, out = tee_stream stream
|
735
|
+
# monitor_thread = Thread.new do
|
736
|
+
# begin
|
737
|
+
# while line = monitor.gets
|
738
|
+
# block.call line
|
739
|
+
# end
|
740
|
+
# rescue
|
741
|
+
# Log.exception $!
|
742
|
+
# monitor.raise $!
|
743
|
+
# monitor.close unless monitor.closed?
|
744
|
+
# monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
745
|
+
# out.raise $! if out.respond_to?(:raise)
|
746
|
+
# ensure
|
747
|
+
# monitor.close unless monitor.closed?
|
748
|
+
# monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
749
|
+
# end
|
750
|
+
# end
|
751
|
+
#
|
752
|
+
# stream.annotate out if stream.respond_to? :annotate
|
753
|
+
# ConcurrentStream.setup out, :threads => monitor_thread
|
754
|
+
# end
|
755
|
+
#
|
756
|
+
# def self.open_gz_pipe
|
757
|
+
# sout = Misc.open_pipe do |sin|
|
758
|
+
# yield sin
|
759
|
+
# sin.close
|
760
|
+
# end
|
761
|
+
#
|
762
|
+
# Open.gzip(sout)
|
763
|
+
# end
|
764
|
+
#
|
765
|
+
#end
|