lockfile 1.3.0 → 1.4.0
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.
- data/lib/{lockfile-1.3.0.rb → lockfile-1.4.0.rb} +89 -53
- data/lib/lockfile.rb +89 -53
- metadata +3 -3
@@ -5,7 +5,7 @@ unless defined? $__lockfile__
|
|
5
5
|
|
6
6
|
class Lockfile
|
7
7
|
#--{{{
|
8
|
-
VERSION = '1.
|
8
|
+
VERSION = '1.4.0'
|
9
9
|
|
10
10
|
class LockError < StandardError; end
|
11
11
|
class StolenLockError < LockError; end
|
@@ -26,8 +26,10 @@ unless defined? $__lockfile__
|
|
26
26
|
#--{{{
|
27
27
|
@min, @max, @inc = Float(min), Float(max), Float(inc)
|
28
28
|
@range = @max - @min
|
29
|
-
raise RangeError, "max
|
30
|
-
raise RangeError, "inc > range" if @inc > @range
|
29
|
+
raise RangeError, "max(#{ @max }) <= min(#{ @min })" if @max <= @min
|
30
|
+
raise RangeError, "inc(#{ @inc }) > range(#{ @range })" if @inc > @range
|
31
|
+
raise RangeError, "inc(#{ @inc }) <= 0" if @inc <= 0
|
32
|
+
raise RangeError, "range(#{ @range }) <= 0" if @range <= 0
|
31
33
|
s = @min
|
32
34
|
push(s) and s += @inc while(s <= @max)
|
33
35
|
self[-1] = @max if self[-1] < @max
|
@@ -51,18 +53,19 @@ unless defined? $__lockfile__
|
|
51
53
|
|
52
54
|
HOSTNAME = Socket::gethostname
|
53
55
|
|
54
|
-
DEFAULT_RETRIES
|
55
|
-
DEFAULT_TIMEOUT
|
56
|
-
DEFAULT_MAX_AGE
|
57
|
-
DEFAULT_SLEEP_INC
|
58
|
-
DEFAULT_MIN_SLEEP
|
59
|
-
DEFAULT_MAX_SLEEP
|
60
|
-
DEFAULT_SUSPEND
|
61
|
-
DEFAULT_REFRESH
|
62
|
-
DEFAULT_DONT_CLEAN
|
63
|
-
DEFAULT_POLL_RETRIES
|
64
|
-
DEFAULT_POLL_MAX_SLEEP
|
65
|
-
DEFAULT_DONT_SWEEP
|
56
|
+
DEFAULT_RETRIES = nil # maximum number of attempts
|
57
|
+
DEFAULT_TIMEOUT = nil # the longest we will try
|
58
|
+
DEFAULT_MAX_AGE = 1024 # lockfiles older than this are stale
|
59
|
+
DEFAULT_SLEEP_INC = 2 # sleep cycle is this much longer each time
|
60
|
+
DEFAULT_MIN_SLEEP = 2 # shortest sleep time
|
61
|
+
DEFAULT_MAX_SLEEP = 32 # longest sleep time
|
62
|
+
DEFAULT_SUSPEND = 64 # iff we steal a lock wait this long before we go on
|
63
|
+
DEFAULT_REFRESH = 8 # how often we touch/validate the lock
|
64
|
+
DEFAULT_DONT_CLEAN = false # iff we leave lock files lying around
|
65
|
+
DEFAULT_POLL_RETRIES = 16 # this many polls makes one 'try'
|
66
|
+
DEFAULT_POLL_MAX_SLEEP = 0.08 # the longest we'll sleep between polls
|
67
|
+
DEFAULT_DONT_SWEEP = false # if we cleanup after other process on our host
|
68
|
+
DEFAULT_DONT_USE_LOCK_ID = false # if we dump lock info into lockfile
|
66
69
|
|
67
70
|
DEFAULT_DEBUG = ENV['LOCKFILE_DEBUG'] || false
|
68
71
|
|
@@ -81,21 +84,23 @@ unless defined? $__lockfile__
|
|
81
84
|
attr :poll_retries, true
|
82
85
|
attr :poll_max_sleep, true
|
83
86
|
attr :dont_sweep, true
|
87
|
+
attr :dont_use_lock_id, true
|
84
88
|
|
85
89
|
def init
|
86
90
|
#--{{{
|
87
|
-
@retries
|
88
|
-
@max_age
|
89
|
-
@sleep_inc
|
90
|
-
@min_sleep
|
91
|
-
@max_sleep
|
92
|
-
@suspend
|
93
|
-
@timeout
|
94
|
-
@refresh
|
95
|
-
@dont_clean
|
96
|
-
@poll_retries
|
97
|
-
@poll_max_sleep
|
98
|
-
@dont_sweep
|
91
|
+
@retries = DEFAULT_RETRIES
|
92
|
+
@max_age = DEFAULT_MAX_AGE
|
93
|
+
@sleep_inc = DEFAULT_SLEEP_INC
|
94
|
+
@min_sleep = DEFAULT_MIN_SLEEP
|
95
|
+
@max_sleep = DEFAULT_MAX_SLEEP
|
96
|
+
@suspend = DEFAULT_SUSPEND
|
97
|
+
@timeout = DEFAULT_TIMEOUT
|
98
|
+
@refresh = DEFAULT_REFRESH
|
99
|
+
@dont_clean = DEFAULT_DONT_CLEAN
|
100
|
+
@poll_retries = DEFAULT_POLL_RETRIES
|
101
|
+
@poll_max_sleep = DEFAULT_POLL_MAX_SLEEP
|
102
|
+
@dont_sweep = DEFAULT_DONT_SWEEP
|
103
|
+
@dont_use_lock_id = DEFAULT_DONT_USE_LOCK_ID
|
99
104
|
|
100
105
|
@debug = DEFAULT_DEBUG
|
101
106
|
|
@@ -127,6 +132,7 @@ unless defined? $__lockfile__
|
|
127
132
|
attr :poll_retries
|
128
133
|
attr :poll_max_sleep
|
129
134
|
attr :dont_sweep
|
135
|
+
attr :dont_use_lock_id
|
130
136
|
|
131
137
|
attr :debug, true
|
132
138
|
|
@@ -134,24 +140,50 @@ unless defined? $__lockfile__
|
|
134
140
|
alias locked? locked
|
135
141
|
alias debug? debug
|
136
142
|
|
143
|
+
def self::create(path, *a, &b)
|
144
|
+
#--{{{
|
145
|
+
opts = {
|
146
|
+
'retries' => 0,
|
147
|
+
'min_sleep' => 0,
|
148
|
+
'max_sleep' => 1,
|
149
|
+
'sleep_inc' => 1,
|
150
|
+
'max_age' => nil,
|
151
|
+
'suspend' => 0,
|
152
|
+
'refresh' => nil,
|
153
|
+
'timeout' => nil,
|
154
|
+
'poll_retries' => 0,
|
155
|
+
'dont_clean' => true,
|
156
|
+
'dont_sweep' => false,
|
157
|
+
'dont_use_lock_id' => true,
|
158
|
+
}
|
159
|
+
begin
|
160
|
+
new(path, opts).lock
|
161
|
+
rescue LockError
|
162
|
+
raise Errno::EEXIST, path
|
163
|
+
end
|
164
|
+
open(path, *a, &b)
|
165
|
+
#--}}}
|
166
|
+
end
|
167
|
+
|
137
168
|
def initialize(path, opts = {}, &block)
|
138
169
|
#--{{{
|
139
170
|
@klass = self.class
|
140
171
|
@path = path
|
141
172
|
@opts = opts
|
142
173
|
|
143
|
-
@retries
|
144
|
-
@max_age
|
145
|
-
@sleep_inc
|
146
|
-
@min_sleep
|
147
|
-
@max_sleep
|
148
|
-
@suspend
|
149
|
-
@timeout
|
150
|
-
@refresh
|
151
|
-
@dont_clean
|
152
|
-
@poll_retries
|
153
|
-
@poll_max_sleep
|
154
|
-
@dont_sweep
|
174
|
+
@retries = getopt('retries') || @klass.retries
|
175
|
+
@max_age = getopt('max_age') || @klass.max_age
|
176
|
+
@sleep_inc = getopt('sleep_inc') || @klass.sleep_inc
|
177
|
+
@min_sleep = getopt('min_sleep') || @klass.min_sleep
|
178
|
+
@max_sleep = getopt('max_sleep') || @klass.max_sleep
|
179
|
+
@suspend = getopt('suspend') || @klass.suspend
|
180
|
+
@timeout = getopt('timeout') || @klass.timeout
|
181
|
+
@refresh = getopt('refresh') || @klass.refresh
|
182
|
+
@dont_clean = getopt('dont_clean') || @klass.dont_clean
|
183
|
+
@poll_retries = getopt('poll_retries') || @klass.poll_retries
|
184
|
+
@poll_max_sleep = getopt('poll_max_sleep') || @klass.poll_max_sleep
|
185
|
+
@dont_sweep = getopt('dont_sweep') || @klass.dont_sweep
|
186
|
+
@dont_use_lock_id = getopt('dont_use_lock_id') || @klass.dont_use_lock_id
|
155
187
|
|
156
188
|
@debug = getopt('debug') || @klass.debug
|
157
189
|
|
@@ -162,7 +194,7 @@ unless defined? $__lockfile__
|
|
162
194
|
@basename = File::basename @path
|
163
195
|
@thief = false
|
164
196
|
@locked = false
|
165
|
-
|
197
|
+
|
166
198
|
lock(&block) if block
|
167
199
|
#--}}}
|
168
200
|
end
|
@@ -338,20 +370,22 @@ unless defined? $__lockfile__
|
|
338
370
|
end
|
339
371
|
def new_refresher
|
340
372
|
#--{{{
|
341
|
-
Thread::new(Thread::current, @path, @refresh) do |thread, path, refresh|
|
373
|
+
Thread::new(Thread::current, @path, @refresh, @dont_use_lock_id) do |thread, path, refresh, dont_use_lock_id|
|
342
374
|
loop do
|
343
|
-
touch path
|
344
|
-
trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
|
345
375
|
begin
|
346
|
-
|
347
|
-
trace{"
|
348
|
-
|
349
|
-
|
376
|
+
touch path
|
377
|
+
trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
|
378
|
+
unless dont_use_lock_id
|
379
|
+
loaded = load_lock_id(IO.read(path))
|
380
|
+
trace{"loaded <\n#{ loaded.inspect }\n>"}
|
381
|
+
raise unless loaded == @lock_id
|
382
|
+
end
|
383
|
+
sleep refresh
|
384
|
+
rescue Exception => e
|
350
385
|
trace{errmsg e}
|
351
386
|
thread.raise StolenLockError
|
352
387
|
Thread::exit
|
353
388
|
end
|
354
|
-
sleep refresh
|
355
389
|
end
|
356
390
|
end
|
357
391
|
#--}}}
|
@@ -395,11 +429,13 @@ unless defined? $__lockfile__
|
|
395
429
|
tmplock = tmpnam @dirname
|
396
430
|
begin
|
397
431
|
create(tmplock) do |f|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
432
|
+
unless dont_use_lock_id
|
433
|
+
@lock_id = gen_lock_id
|
434
|
+
dumped = dump_lock_id
|
435
|
+
trace{"lock_id <\n#{ @lock_id.inspect }\n>"}
|
436
|
+
f.write dumped
|
437
|
+
f.flush
|
438
|
+
end
|
403
439
|
yield f
|
404
440
|
end
|
405
441
|
ensure
|
data/lib/lockfile.rb
CHANGED
@@ -5,7 +5,7 @@ unless defined? $__lockfile__
|
|
5
5
|
|
6
6
|
class Lockfile
|
7
7
|
#--{{{
|
8
|
-
VERSION = '1.
|
8
|
+
VERSION = '1.4.0'
|
9
9
|
|
10
10
|
class LockError < StandardError; end
|
11
11
|
class StolenLockError < LockError; end
|
@@ -26,8 +26,10 @@ unless defined? $__lockfile__
|
|
26
26
|
#--{{{
|
27
27
|
@min, @max, @inc = Float(min), Float(max), Float(inc)
|
28
28
|
@range = @max - @min
|
29
|
-
raise RangeError, "max
|
30
|
-
raise RangeError, "inc > range" if @inc > @range
|
29
|
+
raise RangeError, "max(#{ @max }) <= min(#{ @min })" if @max <= @min
|
30
|
+
raise RangeError, "inc(#{ @inc }) > range(#{ @range })" if @inc > @range
|
31
|
+
raise RangeError, "inc(#{ @inc }) <= 0" if @inc <= 0
|
32
|
+
raise RangeError, "range(#{ @range }) <= 0" if @range <= 0
|
31
33
|
s = @min
|
32
34
|
push(s) and s += @inc while(s <= @max)
|
33
35
|
self[-1] = @max if self[-1] < @max
|
@@ -51,18 +53,19 @@ unless defined? $__lockfile__
|
|
51
53
|
|
52
54
|
HOSTNAME = Socket::gethostname
|
53
55
|
|
54
|
-
DEFAULT_RETRIES
|
55
|
-
DEFAULT_TIMEOUT
|
56
|
-
DEFAULT_MAX_AGE
|
57
|
-
DEFAULT_SLEEP_INC
|
58
|
-
DEFAULT_MIN_SLEEP
|
59
|
-
DEFAULT_MAX_SLEEP
|
60
|
-
DEFAULT_SUSPEND
|
61
|
-
DEFAULT_REFRESH
|
62
|
-
DEFAULT_DONT_CLEAN
|
63
|
-
DEFAULT_POLL_RETRIES
|
64
|
-
DEFAULT_POLL_MAX_SLEEP
|
65
|
-
DEFAULT_DONT_SWEEP
|
56
|
+
DEFAULT_RETRIES = nil # maximum number of attempts
|
57
|
+
DEFAULT_TIMEOUT = nil # the longest we will try
|
58
|
+
DEFAULT_MAX_AGE = 1024 # lockfiles older than this are stale
|
59
|
+
DEFAULT_SLEEP_INC = 2 # sleep cycle is this much longer each time
|
60
|
+
DEFAULT_MIN_SLEEP = 2 # shortest sleep time
|
61
|
+
DEFAULT_MAX_SLEEP = 32 # longest sleep time
|
62
|
+
DEFAULT_SUSPEND = 64 # iff we steal a lock wait this long before we go on
|
63
|
+
DEFAULT_REFRESH = 8 # how often we touch/validate the lock
|
64
|
+
DEFAULT_DONT_CLEAN = false # iff we leave lock files lying around
|
65
|
+
DEFAULT_POLL_RETRIES = 16 # this many polls makes one 'try'
|
66
|
+
DEFAULT_POLL_MAX_SLEEP = 0.08 # the longest we'll sleep between polls
|
67
|
+
DEFAULT_DONT_SWEEP = false # if we cleanup after other process on our host
|
68
|
+
DEFAULT_DONT_USE_LOCK_ID = false # if we dump lock info into lockfile
|
66
69
|
|
67
70
|
DEFAULT_DEBUG = ENV['LOCKFILE_DEBUG'] || false
|
68
71
|
|
@@ -81,21 +84,23 @@ unless defined? $__lockfile__
|
|
81
84
|
attr :poll_retries, true
|
82
85
|
attr :poll_max_sleep, true
|
83
86
|
attr :dont_sweep, true
|
87
|
+
attr :dont_use_lock_id, true
|
84
88
|
|
85
89
|
def init
|
86
90
|
#--{{{
|
87
|
-
@retries
|
88
|
-
@max_age
|
89
|
-
@sleep_inc
|
90
|
-
@min_sleep
|
91
|
-
@max_sleep
|
92
|
-
@suspend
|
93
|
-
@timeout
|
94
|
-
@refresh
|
95
|
-
@dont_clean
|
96
|
-
@poll_retries
|
97
|
-
@poll_max_sleep
|
98
|
-
@dont_sweep
|
91
|
+
@retries = DEFAULT_RETRIES
|
92
|
+
@max_age = DEFAULT_MAX_AGE
|
93
|
+
@sleep_inc = DEFAULT_SLEEP_INC
|
94
|
+
@min_sleep = DEFAULT_MIN_SLEEP
|
95
|
+
@max_sleep = DEFAULT_MAX_SLEEP
|
96
|
+
@suspend = DEFAULT_SUSPEND
|
97
|
+
@timeout = DEFAULT_TIMEOUT
|
98
|
+
@refresh = DEFAULT_REFRESH
|
99
|
+
@dont_clean = DEFAULT_DONT_CLEAN
|
100
|
+
@poll_retries = DEFAULT_POLL_RETRIES
|
101
|
+
@poll_max_sleep = DEFAULT_POLL_MAX_SLEEP
|
102
|
+
@dont_sweep = DEFAULT_DONT_SWEEP
|
103
|
+
@dont_use_lock_id = DEFAULT_DONT_USE_LOCK_ID
|
99
104
|
|
100
105
|
@debug = DEFAULT_DEBUG
|
101
106
|
|
@@ -127,6 +132,7 @@ unless defined? $__lockfile__
|
|
127
132
|
attr :poll_retries
|
128
133
|
attr :poll_max_sleep
|
129
134
|
attr :dont_sweep
|
135
|
+
attr :dont_use_lock_id
|
130
136
|
|
131
137
|
attr :debug, true
|
132
138
|
|
@@ -134,24 +140,50 @@ unless defined? $__lockfile__
|
|
134
140
|
alias locked? locked
|
135
141
|
alias debug? debug
|
136
142
|
|
143
|
+
def self::create(path, *a, &b)
|
144
|
+
#--{{{
|
145
|
+
opts = {
|
146
|
+
'retries' => 0,
|
147
|
+
'min_sleep' => 0,
|
148
|
+
'max_sleep' => 1,
|
149
|
+
'sleep_inc' => 1,
|
150
|
+
'max_age' => nil,
|
151
|
+
'suspend' => 0,
|
152
|
+
'refresh' => nil,
|
153
|
+
'timeout' => nil,
|
154
|
+
'poll_retries' => 0,
|
155
|
+
'dont_clean' => true,
|
156
|
+
'dont_sweep' => false,
|
157
|
+
'dont_use_lock_id' => true,
|
158
|
+
}
|
159
|
+
begin
|
160
|
+
new(path, opts).lock
|
161
|
+
rescue LockError
|
162
|
+
raise Errno::EEXIST, path
|
163
|
+
end
|
164
|
+
open(path, *a, &b)
|
165
|
+
#--}}}
|
166
|
+
end
|
167
|
+
|
137
168
|
def initialize(path, opts = {}, &block)
|
138
169
|
#--{{{
|
139
170
|
@klass = self.class
|
140
171
|
@path = path
|
141
172
|
@opts = opts
|
142
173
|
|
143
|
-
@retries
|
144
|
-
@max_age
|
145
|
-
@sleep_inc
|
146
|
-
@min_sleep
|
147
|
-
@max_sleep
|
148
|
-
@suspend
|
149
|
-
@timeout
|
150
|
-
@refresh
|
151
|
-
@dont_clean
|
152
|
-
@poll_retries
|
153
|
-
@poll_max_sleep
|
154
|
-
@dont_sweep
|
174
|
+
@retries = getopt('retries') || @klass.retries
|
175
|
+
@max_age = getopt('max_age') || @klass.max_age
|
176
|
+
@sleep_inc = getopt('sleep_inc') || @klass.sleep_inc
|
177
|
+
@min_sleep = getopt('min_sleep') || @klass.min_sleep
|
178
|
+
@max_sleep = getopt('max_sleep') || @klass.max_sleep
|
179
|
+
@suspend = getopt('suspend') || @klass.suspend
|
180
|
+
@timeout = getopt('timeout') || @klass.timeout
|
181
|
+
@refresh = getopt('refresh') || @klass.refresh
|
182
|
+
@dont_clean = getopt('dont_clean') || @klass.dont_clean
|
183
|
+
@poll_retries = getopt('poll_retries') || @klass.poll_retries
|
184
|
+
@poll_max_sleep = getopt('poll_max_sleep') || @klass.poll_max_sleep
|
185
|
+
@dont_sweep = getopt('dont_sweep') || @klass.dont_sweep
|
186
|
+
@dont_use_lock_id = getopt('dont_use_lock_id') || @klass.dont_use_lock_id
|
155
187
|
|
156
188
|
@debug = getopt('debug') || @klass.debug
|
157
189
|
|
@@ -162,7 +194,7 @@ unless defined? $__lockfile__
|
|
162
194
|
@basename = File::basename @path
|
163
195
|
@thief = false
|
164
196
|
@locked = false
|
165
|
-
|
197
|
+
|
166
198
|
lock(&block) if block
|
167
199
|
#--}}}
|
168
200
|
end
|
@@ -338,20 +370,22 @@ unless defined? $__lockfile__
|
|
338
370
|
end
|
339
371
|
def new_refresher
|
340
372
|
#--{{{
|
341
|
-
Thread::new(Thread::current, @path, @refresh) do |thread, path, refresh|
|
373
|
+
Thread::new(Thread::current, @path, @refresh, @dont_use_lock_id) do |thread, path, refresh, dont_use_lock_id|
|
342
374
|
loop do
|
343
|
-
touch path
|
344
|
-
trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
|
345
375
|
begin
|
346
|
-
|
347
|
-
trace{"
|
348
|
-
|
349
|
-
|
376
|
+
touch path
|
377
|
+
trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
|
378
|
+
unless dont_use_lock_id
|
379
|
+
loaded = load_lock_id(IO.read(path))
|
380
|
+
trace{"loaded <\n#{ loaded.inspect }\n>"}
|
381
|
+
raise unless loaded == @lock_id
|
382
|
+
end
|
383
|
+
sleep refresh
|
384
|
+
rescue Exception => e
|
350
385
|
trace{errmsg e}
|
351
386
|
thread.raise StolenLockError
|
352
387
|
Thread::exit
|
353
388
|
end
|
354
|
-
sleep refresh
|
355
389
|
end
|
356
390
|
end
|
357
391
|
#--}}}
|
@@ -395,11 +429,13 @@ unless defined? $__lockfile__
|
|
395
429
|
tmplock = tmpnam @dirname
|
396
430
|
begin
|
397
431
|
create(tmplock) do |f|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
432
|
+
unless dont_use_lock_id
|
433
|
+
@lock_id = gen_lock_id
|
434
|
+
dumped = dump_lock_id
|
435
|
+
trace{"lock_id <\n#{ @lock_id.inspect }\n>"}
|
436
|
+
f.write dumped
|
437
|
+
f.flush
|
438
|
+
end
|
403
439
|
yield f
|
404
440
|
end
|
405
441
|
ensure
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: lockfile
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2005-11-
|
6
|
+
version: 1.4.0
|
7
|
+
date: 2005-11-10 00:00:00.000000 -07:00
|
8
8
|
summary: lockfile
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -30,7 +30,7 @@ authors:
|
|
30
30
|
- Ara T. Howard
|
31
31
|
files:
|
32
32
|
- lib/lockfile.rb
|
33
|
-
- lib/lockfile-1.
|
33
|
+
- lib/lockfile-1.4.0.rb
|
34
34
|
- bin/rlock
|
35
35
|
- bin/rlock-1.3.0
|
36
36
|
test_files: []
|