lockfile 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|