scout-gear 9.1.0 → 10.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +1 -78
  3. data/Rakefile +2 -2
  4. data/VERSION +1 -1
  5. data/lib/scout/offsite/exceptions.rb +9 -0
  6. data/lib/scout/offsite/ssh.rb +1 -0
  7. data/lib/scout/semaphore.rb +2 -0
  8. data/lib/scout/tsv/open.rb +1 -1
  9. data/lib/scout/tsv/parser.rb +1 -1
  10. data/lib/scout/tsv/persist/adapter.rb +2 -2
  11. data/lib/scout/tsv/persist.rb +1 -0
  12. data/lib/scout/tsv/util/sort.rb +74 -0
  13. data/lib/scout/tsv/util.rb +1 -0
  14. data/lib/scout/tsv.rb +1 -1
  15. data/lib/scout/work_queue/exceptions.rb +18 -0
  16. data/lib/scout/work_queue.rb +1 -0
  17. data/lib/scout/workflow/definition.rb +1 -1
  18. data/lib/scout/workflow/step/config.rb +1 -1
  19. data/lib/scout/workflow/step/status.rb +1 -0
  20. data/lib/scout/workflow/step.rb +49 -49
  21. data/lib/scout/workflow/task/inputs.rb +1 -1
  22. data/lib/scout/workflow/task.rb +2 -2
  23. data/lib/scout/workflow.rb +2 -2
  24. data/lib/scout-gear.rb +1 -10
  25. data/scout-gear.gemspec +9 -97
  26. data/scout_commands/workflow/task +3 -3
  27. data/test/scout/tsv/test_open.rb +1 -1
  28. data/test/scout/tsv/util/test_sort.rb +23 -0
  29. data/test/scout/workflow/task/test_inputs.rb +0 -4
  30. metadata +8 -109
  31. data/lib/scout/cmd.rb +0 -347
  32. data/lib/scout/concurrent_stream.rb +0 -284
  33. data/lib/scout/config.rb +0 -168
  34. data/lib/scout/exceptions.rb +0 -151
  35. data/lib/scout/indiferent_hash/case_insensitive.rb +0 -30
  36. data/lib/scout/indiferent_hash/options.rb +0 -115
  37. data/lib/scout/indiferent_hash.rb +0 -96
  38. data/lib/scout/log/color.rb +0 -224
  39. data/lib/scout/log/color_class.rb +0 -269
  40. data/lib/scout/log/fingerprint.rb +0 -69
  41. data/lib/scout/log/progress/report.rb +0 -244
  42. data/lib/scout/log/progress/util.rb +0 -173
  43. data/lib/scout/log/progress.rb +0 -106
  44. data/lib/scout/log/trap.rb +0 -107
  45. data/lib/scout/log.rb +0 -441
  46. data/lib/scout/meta_extension.rb +0 -100
  47. data/lib/scout/misc/digest.rb +0 -63
  48. data/lib/scout/misc/filesystem.rb +0 -25
  49. data/lib/scout/misc/format.rb +0 -255
  50. data/lib/scout/misc/helper.rb +0 -31
  51. data/lib/scout/misc/insist.rb +0 -56
  52. data/lib/scout/misc/monitor.rb +0 -66
  53. data/lib/scout/misc/system.rb +0 -73
  54. data/lib/scout/misc.rb +0 -10
  55. data/lib/scout/named_array.rb +0 -138
  56. data/lib/scout/open/lock/lockfile.rb +0 -587
  57. data/lib/scout/open/lock.rb +0 -68
  58. data/lib/scout/open/remote.rb +0 -135
  59. data/lib/scout/open/stream.rb +0 -491
  60. data/lib/scout/open/util.rb +0 -244
  61. data/lib/scout/open.rb +0 -170
  62. data/lib/scout/path/find.rb +0 -204
  63. data/lib/scout/path/tmpfile.rb +0 -8
  64. data/lib/scout/path/util.rb +0 -127
  65. data/lib/scout/path.rb +0 -51
  66. data/lib/scout/persist/open.rb +0 -17
  67. data/lib/scout/persist/path.rb +0 -15
  68. data/lib/scout/persist/serialize.rb +0 -157
  69. data/lib/scout/persist.rb +0 -104
  70. data/lib/scout/resource/open.rb +0 -8
  71. data/lib/scout/resource/path.rb +0 -80
  72. data/lib/scout/resource/produce/rake.rb +0 -69
  73. data/lib/scout/resource/produce.rb +0 -151
  74. data/lib/scout/resource/scout.rb +0 -3
  75. data/lib/scout/resource/software.rb +0 -178
  76. data/lib/scout/resource/util.rb +0 -59
  77. data/lib/scout/resource.rb +0 -41
  78. data/lib/scout/simple_opt/accessor.rb +0 -54
  79. data/lib/scout/simple_opt/doc.rb +0 -126
  80. data/lib/scout/simple_opt/get.rb +0 -57
  81. data/lib/scout/simple_opt/parse.rb +0 -67
  82. data/lib/scout/simple_opt/setup.rb +0 -26
  83. data/lib/scout/simple_opt.rb +0 -5
  84. data/lib/scout/tmpfile.rb +0 -129
  85. data/test/scout/indiferent_hash/test_case_insensitive.rb +0 -16
  86. data/test/scout/indiferent_hash/test_options.rb +0 -46
  87. data/test/scout/log/test_progress.rb +0 -108
  88. data/test/scout/misc/test_digest.rb +0 -30
  89. data/test/scout/misc/test_filesystem.rb +0 -30
  90. data/test/scout/misc/test_insist.rb +0 -13
  91. data/test/scout/misc/test_system.rb +0 -21
  92. data/test/scout/open/test_lock.rb +0 -52
  93. data/test/scout/open/test_remote.rb +0 -25
  94. data/test/scout/open/test_stream.rb +0 -676
  95. data/test/scout/open/test_util.rb +0 -73
  96. data/test/scout/path/test_find.rb +0 -119
  97. data/test/scout/path/test_util.rb +0 -22
  98. data/test/scout/persist/test_open.rb +0 -37
  99. data/test/scout/persist/test_path.rb +0 -37
  100. data/test/scout/persist/test_serialize.rb +0 -114
  101. data/test/scout/resource/test_path.rb +0 -46
  102. data/test/scout/resource/test_produce.rb +0 -92
  103. data/test/scout/resource/test_software.rb +0 -24
  104. data/test/scout/resource/test_util.rb +0 -36
  105. data/test/scout/simple_opt/test_doc.rb +0 -16
  106. data/test/scout/simple_opt/test_get.rb +0 -11
  107. data/test/scout/simple_opt/test_parse.rb +0 -10
  108. data/test/scout/simple_opt/test_setup.rb +0 -77
  109. data/test/scout/test_cmd.rb +0 -85
  110. data/test/scout/test_concurrent_stream.rb +0 -29
  111. data/test/scout/test_config.rb +0 -66
  112. data/test/scout/test_indiferent_hash.rb +0 -26
  113. data/test/scout/test_log.rb +0 -32
  114. data/test/scout/test_meta_extension.rb +0 -80
  115. data/test/scout/test_misc.rb +0 -6
  116. data/test/scout/test_named_array.rb +0 -43
  117. data/test/scout/test_open.rb +0 -146
  118. data/test/scout/test_path.rb +0 -54
  119. data/test/scout/test_persist.rb +0 -186
  120. data/test/scout/test_resource.rb +0 -26
  121. data/test/scout/test_tmpfile.rb +0 -53
  122. /data/test/scout/{log/test_color.rb → test_offsite.rb} +0 -0
@@ -1,587 +0,0 @@
1
- # Originaly from here https://github.com/ahoward/lockfile
2
- # Author: Ara T. Howard (Ara T. Howard)
3
- # Licence: Ruby (as listed [here](https://github.com/ahoward/lockfile/blob/20ab06f29bda69b9773d799510d00585b6a27e3b/lockfile.gemspec#L10))
4
- # with modifications for scout-gear and rbbt by Miguel Vazquez
5
- unless(defined?($__lockfile__) or defined?(Lockfile))
6
-
7
- require 'socket'
8
- require 'timeout'
9
- require 'fileutils'
10
-
11
- class Lockfile
12
-
13
- VERSION = '2.1.8'
14
- def Lockfile.version() Lockfile::VERSION end
15
- def version() Lockfile::VERSION end
16
-
17
- def Lockfile.description
18
- 'a ruby library for creating perfect and NFS safe lockfiles'
19
- end
20
-
21
- class LockError < StandardError; end
22
- class StolenLockError < LockError; end
23
- class StackingLockError < LockError; end
24
- class StatLockError < LockError; end
25
- class MaxTriesLockError < LockError; end
26
- class TimeoutLockError < LockError; end
27
- class NFSLockError < LockError; end
28
- class UnLockError < LockError; end
29
-
30
- class SleepCycle < Array
31
- attr_reader :min
32
- attr_reader :max
33
- attr_reader :range
34
- attr_reader :inc
35
-
36
- def initialize(min, max, inc)
37
- @min, @max, @inc = Float(min), Float(max), Float(inc)
38
- @range = @max - @min
39
- raise RangeError, "max(#{ @max }) <= min(#{ @min })" if @max <= @min
40
- raise RangeError, "inc(#{ @inc }) > range(#{ @range })" if @inc > @range
41
- raise RangeError, "inc(#{ @inc }) <= 0" if @inc <= 0
42
- raise RangeError, "range(#{ @range }) <= 0" if @range <= 0
43
- s = @min
44
- push(s) and s += @inc while(s <= @max)
45
- self[-1] = @max if self[-1] < @max
46
- reset
47
- end
48
-
49
- def next
50
- ret = self[@idx]
51
- @idx = ((@idx + 1) % self.size)
52
- ret
53
- end
54
-
55
- def reset
56
- @idx = 0
57
- end
58
- end
59
-
60
- HOSTNAME = Socket.gethostname
61
-
62
- DEFAULT_RETRIES = nil # maximum number of attempts
63
- DEFAULT_TIMEOUT = nil # the longest we will try
64
- DEFAULT_MAX_AGE = 3600 # lockfiles older than this are stale
65
- DEFAULT_SLEEP_INC = 2 # sleep cycle is this much longer each time
66
- DEFAULT_MIN_SLEEP = 2 # shortest sleep time
67
- DEFAULT_MAX_SLEEP = 32 # longest sleep time
68
- DEFAULT_SUSPEND = 1800 # iff we steal a lock wait this long before we go on
69
- DEFAULT_REFRESH = 8 # how often we touch/validate the lock
70
- DEFAULT_DONT_CLEAN = false # iff we leave lock files lying around
71
- DEFAULT_POLL_RETRIES = 16 # this many polls makes one 'try'
72
- DEFAULT_POLL_MAX_SLEEP = 0.08 # the longest we'll sleep between polls
73
- DEFAULT_DONT_SWEEP = false # if we cleanup after other process on our host
74
- DEFAULT_DONT_USE_LOCK_ID = false # if we dump lock info into lockfile
75
-
76
- DEFAULT_DEBUG = ENV['LOCKFILE_DEBUG'] || false
77
-
78
- class << Lockfile
79
- attr_accessor :retries
80
- attr_accessor :max_age
81
- attr_accessor :sleep_inc
82
- attr_accessor :min_sleep
83
- attr_accessor :max_sleep
84
- attr_accessor :suspend
85
- attr_accessor :timeout
86
- attr_accessor :refresh
87
- attr_accessor :debug
88
- attr_accessor :dont_clean
89
- attr_accessor :poll_retries
90
- attr_accessor :poll_max_sleep
91
- attr_accessor :dont_sweep
92
- attr_accessor :dont_use_lock_id
93
-
94
- def init
95
- @retries = DEFAULT_RETRIES
96
- @max_age = DEFAULT_MAX_AGE
97
- @sleep_inc = DEFAULT_SLEEP_INC
98
- @min_sleep = DEFAULT_MIN_SLEEP
99
- @max_sleep = DEFAULT_MAX_SLEEP
100
- @suspend = DEFAULT_SUSPEND
101
- @timeout = DEFAULT_TIMEOUT
102
- @refresh = DEFAULT_REFRESH
103
- @dont_clean = DEFAULT_DONT_CLEAN
104
- @poll_retries = DEFAULT_POLL_RETRIES
105
- @poll_max_sleep = DEFAULT_POLL_MAX_SLEEP
106
- @dont_sweep = DEFAULT_DONT_SWEEP
107
- @dont_use_lock_id = DEFAULT_DONT_USE_LOCK_ID
108
-
109
- @debug = DEFAULT_DEBUG
110
-
111
- STDOUT.sync = true if @debug
112
- STDERR.sync = true if @debug
113
- end
114
- end
115
-
116
- Lockfile.init
117
-
118
- attr_reader :klass
119
- attr_reader :path
120
- attr_reader :opts
121
- attr_reader :locked
122
- attr_reader :thief
123
- attr_reader :refresher
124
- attr_reader :dirname
125
- attr_reader :basename
126
- attr_reader :clean
127
- attr_reader :retries
128
- attr_reader :max_age
129
- attr_reader :sleep_inc
130
- attr_reader :min_sleep
131
- attr_reader :max_sleep
132
- attr_reader :suspend
133
- attr_reader :refresh
134
- attr_reader :timeout
135
- attr_reader :dont_clean
136
- attr_reader :poll_retries
137
- attr_reader :poll_max_sleep
138
- attr_reader :dont_sweep
139
- attr_reader :dont_use_lock_id
140
-
141
- attr_accessor :debug
142
-
143
- alias thief? thief
144
- alias locked? locked
145
- alias debug? debug
146
-
147
- def Lockfile.create(path, *a, &b)
148
- opts = {
149
- 'retries' => 0,
150
- 'min_sleep' => 0,
151
- 'max_sleep' => 1,
152
- 'sleep_inc' => 1,
153
- 'max_age' => nil,
154
- 'suspend' => 0,
155
- 'refresh' => nil,
156
- 'timeout' => nil,
157
- 'poll_retries' => 0,
158
- 'dont_clean' => true,
159
- 'dont_sweep' => false,
160
- 'dont_use_lock_id' => true,
161
- }
162
- begin
163
- new(path, opts).lock
164
- rescue LockError
165
- raise Errno::EEXIST, path
166
- end
167
- open(path, *a, &b)
168
- end
169
-
170
- def self.finalizer_proc(file)
171
- pid = Process.pid
172
- lambda do |id|
173
- File.unlink file if Process.pid == pid
174
- rescue
175
- nil
176
- end
177
- end
178
-
179
- def initialize(path, opts = {}, &block)
180
- @klass = self.class
181
- @path = path
182
- @opts = opts
183
-
184
- @retries = getopt 'retries' , @klass.retries
185
- @max_age = getopt 'max_age' , @klass.max_age
186
- @sleep_inc = getopt 'sleep_inc' , @klass.sleep_inc
187
- @min_sleep = getopt 'min_sleep' , @klass.min_sleep
188
- @max_sleep = getopt 'max_sleep' , @klass.max_sleep
189
- @suspend = getopt 'suspend' , @klass.suspend
190
- @timeout = getopt 'timeout' , @klass.timeout
191
- @refresh = getopt 'refresh' , @klass.refresh
192
- @dont_clean = getopt 'dont_clean' , @klass.dont_clean
193
- @poll_retries = getopt 'poll_retries' , @klass.poll_retries
194
- @poll_max_sleep = getopt 'poll_max_sleep' , @klass.poll_max_sleep
195
- @dont_sweep = getopt 'dont_sweep' , @klass.dont_sweep
196
- @dont_use_lock_id = getopt 'dont_use_lock_id' , @klass.dont_use_lock_id
197
- @debug = getopt 'debug' , @klass.debug
198
-
199
- @semaphore = Mutex.new
200
-
201
- @sleep_cycle = SleepCycle.new @min_sleep, @max_sleep, @sleep_inc
202
-
203
- @clean = @dont_clean ? nil : Lockfile.finalizer_proc(@path)
204
-
205
- @dirname = File.dirname @path
206
- @basename = File.basename @path
207
- @thief = false
208
- @locked = false
209
- @refrsher = nil
210
-
211
- lock(&block) if block
212
- end
213
-
214
- ##
215
- # Executes the given block after acquiring the lock and
216
- # ensures that the lock is relinquished afterwards.
217
- #
218
- def synchronize
219
- raise ArgumentError, 'block must be given' unless block_given?
220
- begin
221
- lock
222
- yield
223
- ensure
224
- unlock
225
- end
226
- end
227
-
228
- def lock
229
- raise StackingLockError, "<#{ @path }> is locked!" if @locked
230
-
231
- sweep unless @dont_sweep
232
-
233
- ret = nil
234
-
235
- attempt do
236
- begin
237
- @sleep_cycle.reset
238
- create_tmplock do |f|
239
- begin
240
- Timeout.timeout(@timeout) do
241
- tmp_path = f.path
242
- tmp_stat = f.lstat
243
- n_retries = 0
244
- trace{ "attempting to lock <#{ @path }>..." }
245
- begin
246
- i = 0
247
- begin
248
- trace{ "polling attempt <#{ i }>..." }
249
- begin
250
- File.link tmp_path, @path
251
- rescue Errno::ENOENT
252
- try_again!
253
- end
254
- lock_stat = File.lstat @path
255
- raise StatLockError, "stat's do not agree" unless
256
- tmp_stat.rdev == lock_stat.rdev and tmp_stat.ino == lock_stat.ino
257
- trace{ "aquired lock <#{ @path }>" }
258
- @locked = true
259
- rescue => e
260
- i += 1
261
- unless i >= @poll_retries
262
- t = [rand(@poll_max_sleep), @poll_max_sleep].min
263
- trace{ "poll sleep <#{ t }>..." }
264
- sleep t
265
- retry
266
- end
267
- raise
268
- end
269
-
270
- rescue => e
271
- n_retries += 1
272
- trace{ "n_retries <#{ n_retries }>" }
273
- case validlock?
274
- when true
275
- raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
276
- @retries and n_retries >= @retries
277
- trace{ "found valid lock" }
278
- sleeptime = @sleep_cycle.next
279
- trace{ "sleep <#{ sleeptime }>..." }
280
- sleep sleeptime
281
- when false
282
- trace{ "found invalid lock and removing" }
283
- begin
284
- File.unlink @path
285
- @thief = true
286
- warn "<#{ @path }> stolen by <#{ Process.pid }> at <#{ timestamp }>"
287
- trace{ "i am a thief!" }
288
- rescue Errno::ENOENT
289
- end
290
- trace{ "suspending <#{ @suspend }>" }
291
- sleep @suspend
292
- when nil
293
- raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
294
- @retries and n_retries >= @retries
295
- end
296
- retry
297
- end # begin
298
- end # timeout
299
- rescue Timeout::Error
300
- raise TimeoutLockError, "surpassed timeout <#{ @timeout }>"
301
- end # begin
302
- end # create_tmplock
303
-
304
- if block_given?
305
- stolen = false
306
- @refresher = (@refresh ? new_refresher : nil)
307
- begin
308
- begin
309
- ret = yield @path
310
- rescue StolenLockError
311
- stolen = true
312
- raise
313
- end
314
- ensure
315
- begin
316
- begin
317
- @semaphore.synchronize do
318
- @refresher.kill
319
- end
320
- rescue
321
- @refresher.kill
322
- end if @refresher and @refresher.status
323
- @refresher = nil
324
- ensure
325
- unlock unless stolen
326
- end
327
- end
328
- else
329
- @refresher = (@refresh ? new_refresher : nil)
330
- ObjectSpace.define_finalizer self, @clean if @clean
331
- ret = self
332
- end
333
- rescue Errno::ESTALE, Errno::EIO => e
334
- raise(NFSLockError, errmsg(e))
335
- end
336
- end
337
-
338
- return ret
339
- end
340
-
341
- def sweep
342
- begin
343
- glob = File.join(@dirname, ".*lck")
344
- paths = Dir[glob]
345
- paths.each do |path|
346
- begin
347
- basename = File.basename path
348
- pat = %r/^\s*\.([^_]+)_([^_]+)/o
349
- if pat.match(basename)
350
- host, pid = $1, $2
351
- else
352
- next
353
- end
354
- host.gsub!(%r/^\.+|\.+$/,'')
355
- quad = host.split %r/\./
356
- host = quad.first
357
- pat = %r/^\s*#{ host }/i
358
- if pat.match(HOSTNAME) and %r/^\s*\d+\s*$/.match(pid)
359
- unless alive?(pid)
360
- trace{ "process <#{ pid }> on <#{ host }> is no longer alive" }
361
- trace{ "sweeping <#{ path }>" }
362
- FileUtils.rm_f path
363
- else
364
- trace{ "process <#{ pid }> on <#{ host }> is still alive" }
365
- trace{ "ignoring <#{ path }>" }
366
- end
367
- else
368
- trace{ "ignoring <#{ path }> generated by <#{ host }>" }
369
- end
370
- rescue
371
- next
372
- end
373
- end
374
- rescue => e
375
- warn(errmsg(e))
376
- end
377
- end
378
-
379
- def alive? pid
380
- pid = Integer("#{ pid }")
381
- begin
382
- Process.kill 0, pid
383
- true
384
- rescue Errno::ESRCH
385
- false
386
- end
387
- end
388
-
389
- def unlock
390
- raise UnLockError, "<#{ @path }> is not locked!" unless @locked
391
-
392
- begin
393
- @semaphore.synchronize do
394
- @refresher.kill
395
- end
396
- rescue
397
- @refresher.kill
398
- end if @refresher and @refresher.status
399
-
400
- @refresher = nil
401
-
402
- begin
403
- File.unlink @path
404
- rescue Errno::ENOENT
405
- raise StolenLockError, @path
406
- ensure
407
- @thief = false
408
- @locked = false
409
- ObjectSpace.undefine_finalizer self if @clean
410
- end
411
- end
412
-
413
- def new_refresher
414
- Thread.new(Thread.current, @path, @refresh, @dont_use_lock_id) do |thread, path, refresh, dont_use_lock_id|
415
- loop do
416
- begin
417
- touch path
418
- trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
419
- unless dont_use_lock_id
420
- txt = nil
421
- @semaphore.synchronize do
422
- txt = IO.read(path)
423
- end
424
- loaded = load_lock_id(txt)
425
- trace{"loaded <\n#{ loaded.inspect }\n>"}
426
- raise unless loaded == @lock_id
427
- end
428
- sleep refresh
429
- rescue Exception => e
430
- trace{errmsg e}
431
- thread.raise StolenLockError
432
- Thread.exit
433
- end
434
- end
435
- end
436
- end
437
-
438
- def validlock?
439
- if @max_age
440
- uncache @path rescue nil
441
- begin
442
- return((Time.now - File.stat(@path).mtime) < @max_age)
443
- rescue Errno::ENOENT
444
- return nil
445
- end
446
- else
447
- exist = File.exist?(@path)
448
- return(exist ? true : nil)
449
- end
450
- end
451
-
452
- def uncache file
453
- refresh = nil
454
- begin
455
- is_a_file = File === file
456
- path = (is_a_file ? file.path : file.to_s)
457
- stat = (is_a_file ? file.stat : File.stat(file.to_s))
458
- refresh = tmpnam(File.dirname(path))
459
- File.link path, refresh
460
- File.chmod stat.mode, path
461
- File.utime stat.atime, stat.mtime, path
462
- ensure
463
- begin
464
- File.unlink refresh if refresh
465
- rescue Errno::ENOENT
466
- end
467
- end
468
- end
469
-
470
- def create_tmplock
471
- tmplock = tmpnam @dirname
472
- begin
473
- create(tmplock) do |f|
474
- unless dont_use_lock_id
475
- @lock_id = gen_lock_id
476
- dumped = dump_lock_id
477
- trace{"lock_id <\n#{ @lock_id.inspect }\n>"}
478
- f.write dumped
479
- f.flush
480
- end
481
- yield f
482
- end
483
- ensure
484
- begin; File.unlink tmplock; rescue Errno::ENOENT; end if tmplock
485
- end
486
- end
487
-
488
- def gen_lock_id
489
- Hash[
490
- 'host' => "#{ HOSTNAME }",
491
- 'pid' => "#{ Process.pid }",
492
- 'ppid' => "#{ Process.ppid }",
493
- 'time' => timestamp,
494
- ]
495
- end
496
-
497
- def timestamp
498
- time = Time.now
499
- usec = time.usec.to_s
500
- usec << '0' while usec.size < 6
501
- "#{ time.strftime('%Y-%m-%d %H:%M:%S') }.#{ usec }"
502
- end
503
-
504
- def dump_lock_id(lock_id = @lock_id)
505
- "host: %s\npid: %s\nppid: %s\ntime: %s\n" %
506
- lock_id.values_at('host','pid','ppid','time')
507
- end
508
-
509
- def load_lock_id(buf)
510
- lock_id = {}
511
- kv = %r/([^:]+):(.*)/o
512
- buf.each_line do |line|
513
- m = kv.match line
514
- k, v = m[1], m[2]
515
- next unless m and k and v
516
- lock_id[k.strip] = v.strip
517
- end
518
- lock_id
519
- end
520
-
521
- def tmpnam(dir, seed = File.basename($0))
522
- pid = Process.pid
523
- time = Time.now
524
- sec = time.to_i
525
- usec = time.usec
526
- "%s%s.%s_%d_%s_%d_%d_%d.lck" %
527
- [dir, File::SEPARATOR, HOSTNAME, pid, seed, sec, usec, rand(sec)]
528
- end
529
-
530
- def create(path)
531
- umask = nil
532
- f = nil
533
- begin
534
- umask = File.umask 022
535
- f = open path, File::WRONLY|File::CREAT|File::EXCL, 0644
536
- ensure
537
- File.umask umask if umask
538
- end
539
- return(block_given? ? begin; yield f; ensure; f.close; end : f)
540
- end
541
-
542
- def touch(path)
543
- FileUtils.touch path
544
- end
545
-
546
- def getopt(key, default = nil)
547
- [ key, key.to_s, key.to_s.intern ].each do |k|
548
- return @opts[k] if @opts.has_key?(k)
549
- end
550
- return default
551
- end
552
-
553
- def to_str
554
- @path
555
- end
556
- alias to_s to_str
557
-
558
- def trace(s = nil)
559
- STDERR.puts((s ? s : yield)) if @debug
560
- end
561
-
562
- def errmsg(e)
563
- "%s (%s)\n%s\n" % [e.class, e.message, e.backtrace.join("\n")]
564
- end
565
-
566
- def attempt
567
- ret = nil
568
- loop{ break unless catch('attempt'){ ret = yield } == 'try_again' }
569
- ret
570
- end
571
-
572
- def try_again!
573
- throw 'attempt', 'try_again'
574
- end
575
- alias again! try_again!
576
-
577
- def give_up!
578
- throw 'attempt', 'give_up'
579
- end
580
- end
581
-
582
- def Lockfile(path, *a, &b)
583
- Lockfile.new(path, *a, &b)
584
- end
585
-
586
- $__lockfile__ = __FILE__
587
- end
@@ -1,68 +0,0 @@
1
- require_relative '../path'
2
- require_relative '../log'
3
- require_relative '../exceptions'
4
- require_relative 'lock/lockfile'
5
-
6
- module Open
7
- def self.init_lock
8
- Lockfile.refresh = 2
9
- Lockfile.max_age = 30
10
- Lockfile.suspend = 4
11
- end
12
-
13
- self.init_lock
14
-
15
- def self.lock(file, unlock = true, options = {})
16
- unlock, options = true, unlock if Hash === unlock
17
- return yield if file.nil? and not Lockfile === options[:lock]
18
-
19
- if Lockfile === file
20
- lockfile = file
21
- else
22
- file = file.find if Path === file
23
- FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exist? File.dirname(File.expand_path(file))
24
-
25
- case options[:lock]
26
- when Lockfile
27
- lockfile = options[:lock]
28
- when FalseClass
29
- lockfile = nil
30
- unlock = false
31
- when Path, String
32
- lock_path = options[:lock].find
33
- lockfile = Lockfile.new(lock_path, options)
34
- else
35
- lock_path = File.expand_path(file + '.lock')
36
- lockfile = Lockfile.new(lock_path, options)
37
- end
38
- end
39
-
40
- begin
41
- lockfile.lock unless lockfile.nil? || lockfile.locked?
42
- rescue Aborted, Interrupt
43
- raise LockInterrupted
44
- end
45
-
46
- res = nil
47
-
48
- begin
49
- res = yield lockfile
50
- rescue KeepLocked
51
- unlock = false
52
- res = $!.payload
53
- ensure
54
- if unlock
55
- begin
56
- if lockfile.locked?
57
- lockfile.unlock
58
- end
59
- rescue Exception
60
- Log.warn "Exception unlocking: #{lockfile.path}"
61
- Log.exception $!
62
- end
63
- end
64
- end
65
-
66
- res
67
- end
68
- end