lockfile 1.1.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rlock +125 -109
- data/bin/rlock-1.3.0 +342 -0
- data/lib/lockfile-1.3.0.rb +518 -0
- data/lib/lockfile.rb +286 -205
- metadata +16 -33
- data/BUGS +0 -3
- data/README +0 -165
- data/VERSION +0 -1
- data/doc/rlock.help +0 -88
- data/install.rb +0 -143
- data/lib/lockfile-1.1.0.rb +0 -437
- data/lockfile-1.1.0.gem +0 -0
- data/lockfile.gemspec +0 -22
- data/samples/a.rb +0 -112
- data/samples/nfsstore.rb +0 -203
- data/samples/test.db +0 -0
- data/samples/test.db~ +0 -0
metadata
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version:
|
2
|
+
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:
|
8
|
-
summary:
|
6
|
+
version: 1.3.0
|
7
|
+
date: 2005-11-03 00:00:00.000000 -07:00
|
8
|
+
summary: lockfile
|
9
9
|
require_paths:
|
10
|
-
- "."
|
11
10
|
- lib
|
12
|
-
|
13
|
-
|
14
|
-
homepage: http://www.codeforpeople.com/lib/ruby/lockfile/
|
11
|
+
email: ara.t.howard@noaa.gov
|
12
|
+
homepage: http://codeforpeople.com/lib/ruby/lockfile/
|
15
13
|
rubyforge_project:
|
16
|
-
description:
|
14
|
+
description:
|
17
15
|
autorequire: lockfile
|
18
16
|
default_executable:
|
19
17
|
bindir: bin
|
@@ -26,34 +24,19 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
26
24
|
version: 0.0.0
|
27
25
|
version:
|
28
26
|
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
authors:
|
30
|
+
- Ara T. Howard
|
29
31
|
files:
|
30
|
-
- install.rb
|
31
|
-
- VERSION
|
32
|
-
- BUGS
|
33
|
-
- lib
|
34
|
-
- bin
|
35
|
-
- samples
|
36
|
-
- doc
|
37
|
-
- lockfile.gemspec
|
38
|
-
- lockfile-1.1.0.gem
|
39
|
-
- README
|
40
32
|
- lib/lockfile.rb
|
41
|
-
- lib/lockfile-1.
|
33
|
+
- lib/lockfile-1.3.0.rb
|
42
34
|
- bin/rlock
|
43
|
-
-
|
44
|
-
- samples/nfsstore.rb
|
45
|
-
- samples/test.db
|
46
|
-
- samples/test.db~
|
47
|
-
- doc/rlock.help
|
35
|
+
- bin/rlock-1.3.0
|
48
36
|
test_files: []
|
49
|
-
rdoc_options:
|
50
|
-
|
51
|
-
|
52
|
-
extra_rdoc_files:
|
53
|
-
- README
|
54
|
-
- doc/rlock.help
|
55
|
-
executables:
|
56
|
-
- rlock
|
37
|
+
rdoc_options: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
executables: []
|
57
40
|
extensions: []
|
58
41
|
requirements: []
|
59
42
|
dependencies: []
|
data/BUGS
DELETED
data/README
DELETED
@@ -1,165 +0,0 @@
|
|
1
|
-
= URLS
|
2
|
-
|
3
|
-
http://raa.ruby-lang.org/project/lockfile/
|
4
|
-
http://www.codeforpeople.com/lib/ruby/lockfile/
|
5
|
-
|
6
|
-
= SYNOPSIS
|
7
|
-
|
8
|
-
lib/lockfile.rb : a ruby library for creating NFS safe lockfiles
|
9
|
-
|
10
|
-
bin/rlock : ruby command line tool which uses this library to create
|
11
|
-
lockfiles. run 'rlock -h' for more info
|
12
|
-
|
13
|
-
= INSTALL
|
14
|
-
|
15
|
-
sudo ruby install.rb
|
16
|
-
|
17
|
-
|
18
|
-
= BASIC ALGORITHIM
|
19
|
-
|
20
|
-
* create a globally uniq filename in the same filesystem as the desired
|
21
|
-
lockfile - this can be nfs mounted
|
22
|
-
|
23
|
-
* link(2) this file to the desired lockfile, ignore all errors
|
24
|
-
|
25
|
-
* stat the uniq filename and desired lockfile to determine is they are the
|
26
|
-
same, use only stat.rdev and stat.ino - ignore stat.nlink as NFS can cause
|
27
|
-
this report incorrect values
|
28
|
-
|
29
|
-
* iff same, you have lock. either return or run optional code block with
|
30
|
-
optional refresher thread keeping lockfile fresh during execution of code
|
31
|
-
block, ensuring that the lockfile is removed..
|
32
|
-
|
33
|
-
* iff not same try again a few times in rapid succession (poll), then, iff
|
34
|
-
this fails, sleep using incremental backoff time. optionally remove
|
35
|
-
lockfile if it is older than a certain time, timeout if more than a certain
|
36
|
-
amount of time has passed attempting to lock file.
|
37
|
-
|
38
|
-
|
39
|
-
= BASIC USAGE
|
40
|
-
|
41
|
-
1)
|
42
|
-
lockfile = Lockfile.new 'file.lock'
|
43
|
-
begin
|
44
|
-
lockfile.lock
|
45
|
-
p 42
|
46
|
-
ensure
|
47
|
-
lockfile.unlock
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
2)
|
52
|
-
require 'pstore' # which is NOT nfs safe on it's own
|
53
|
-
|
54
|
-
opts = { # the keys can be symbols or strings
|
55
|
-
|
56
|
-
:retries => nil, # we will try forever to aquire the lock
|
57
|
-
|
58
|
-
:sleep_inc => 2, # we will sleep 2 seconds longer than the
|
59
|
-
# previous sleep after each retry, cycling from
|
60
|
-
# min_sleep upto max_sleep downto min_sleep upto
|
61
|
-
# max_sleep, etc., etc.
|
62
|
-
|
63
|
-
:min_sleep => 2, # we will never sleep less than 2 seconds
|
64
|
-
|
65
|
-
:max_sleep => 32, # we will never sleep longer than 32 seconds
|
66
|
-
|
67
|
-
:max_age => 1024, # we will blow away any files found to be older
|
68
|
-
# than this (lockfile.thief? #=> true)
|
69
|
-
|
70
|
-
:suspend => 64, # iff we steal the lock from someone else - wait
|
71
|
-
# this long to give them a chance to realize it
|
72
|
-
|
73
|
-
:refresh => 8, # we will spawn a bg thread that touches file
|
74
|
-
# every 8 sec. this thread also causes a
|
75
|
-
# StolenLockError to be thrown if the lock
|
76
|
-
# disappears from under us - note that the
|
77
|
-
# 'detection' rate is limited to the refresh
|
78
|
-
# interval - this is a race condition
|
79
|
-
|
80
|
-
:timeout => nil, # we will wait forever
|
81
|
-
|
82
|
-
:poll_retries => 16, # the initial attempt to grab a lock is done in a
|
83
|
-
# polling fashion, this number controls how many
|
84
|
-
# times this is done - the total polling attempts
|
85
|
-
# are considered ONE actual attempt (see retries
|
86
|
-
# above)
|
87
|
-
|
88
|
-
:poll_max_sleep => 0.08, # when polling a very brief sleep is issued
|
89
|
-
# between attempts, this is the upper limit of
|
90
|
-
# that sleep timeout
|
91
|
-
|
92
|
-
:debug => true, # trace execution step on stdout
|
93
|
-
}
|
94
|
-
|
95
|
-
pstore = PStore.new 'file.db'
|
96
|
-
lockfile = Lockfile.new 'file.db.lock', opts
|
97
|
-
lockfile.lock do
|
98
|
-
pstore.transaction do
|
99
|
-
pstore[:last_update_time] = Time.now
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
3) same as 1 above - Lockfile.new takes a block and ensures unlock is called
|
104
|
-
|
105
|
-
Lockfile.new('file.lock') do
|
106
|
-
p 42
|
107
|
-
end
|
108
|
-
|
109
|
-
4) watch locking algorithim in action
|
110
|
-
|
111
|
-
Lockfile.debug = true
|
112
|
-
Lockfile.new('file.lock') do
|
113
|
-
p 42
|
114
|
-
end
|
115
|
-
|
116
|
-
you can also set debugging via the ENV var LOCKFILE_DEBUG, eg.
|
117
|
-
|
118
|
-
~ > LOCKFILE_DEBUG=true rlock lockfile
|
119
|
-
|
120
|
-
= SAMPLES
|
121
|
-
|
122
|
-
* see samples/a.rb
|
123
|
-
* see samples/nfsstore.rb
|
124
|
-
* see bin/rlock
|
125
|
-
|
126
|
-
= AUTHOR
|
127
|
-
|
128
|
-
-a
|
129
|
-
|
130
|
-
= EMAIL
|
131
|
-
|
132
|
-
Ara.T.Howard@noaa.gov
|
133
|
-
|
134
|
-
= BUGS
|
135
|
-
|
136
|
-
> 1
|
137
|
-
|
138
|
-
further notifications to email above
|
139
|
-
|
140
|
-
= HISTORY
|
141
|
-
|
142
|
-
1.0.1:
|
143
|
-
- fixed bugette in sleep cycle where repeated locks with same lockfile would
|
144
|
-
not reset the cycle at the start of each lock
|
145
|
-
1.0.0:
|
146
|
-
- allow rertries to be nil, meaning to try forever
|
147
|
-
- default timeout is now nil - never timeout
|
148
|
-
- default refresh is now 8
|
149
|
-
- fixed bug where refresher thread was not actually touching lockfile! (ouch)
|
150
|
-
- added cycle method to timeouts
|
151
|
-
1-2-3-2-1-2-3-1...
|
152
|
-
pattern is constructed using min_sleep, sleep_inc, max_sleep
|
153
|
-
0.3.0:
|
154
|
-
- removed use of yaml in favour of hand parsing the lockfile contents, the
|
155
|
-
file as so small it just wasn't worth and i have had one core dump when yaml
|
156
|
-
failed to parse a (corrupt) file
|
157
|
-
0.2.0:
|
158
|
-
- added an initial polling style attempt to grab lock before entering normal
|
159
|
-
sleep/retry loop. this has really helped performance when lock is under
|
160
|
-
heavy contention: i see almost no sleeping done by any of in the interested
|
161
|
-
processes
|
162
|
-
0.1.0:
|
163
|
-
- added ability of Lockfile.new to accept a block
|
164
|
-
0.0.0:
|
165
|
-
- initial version
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.1.0
|
data/doc/rlock.help
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
= NAME
|
2
|
-
rlock v0.0.0
|
3
|
-
|
4
|
-
= SYNOPSIS
|
5
|
-
rlock [options]+ file.lock [program [-- [options]+] [args]+]
|
6
|
-
|
7
|
-
= DESCRIPTTION
|
8
|
-
rlock creates NFS resistent lockfiles
|
9
|
-
|
10
|
-
= ENVIRONMENT
|
11
|
-
LOCKFILE_DEBUG=1 will show internal actions of the library
|
12
|
-
|
13
|
-
= DIAGNOSTICS
|
14
|
-
success => $? == 0
|
15
|
-
failure => $? != 0
|
16
|
-
|
17
|
-
= AUTHOR
|
18
|
-
ara.t.howard@noaa.gov
|
19
|
-
|
20
|
-
= BUGS
|
21
|
-
> 1
|
22
|
-
|
23
|
-
= OPTIONS
|
24
|
-
|
25
|
-
-r, --retries=n
|
26
|
-
-a, --max_age=n
|
27
|
-
-s, --sleep_inc=n
|
28
|
-
-p, --max_sleep=n
|
29
|
-
-u, --suspend=n
|
30
|
-
-t, --timeout=n
|
31
|
-
-f, --refresh=n
|
32
|
-
-d, --debug
|
33
|
-
-v=0-4|debug|info|warn|error|fatal
|
34
|
-
--verbosity
|
35
|
-
-l, --log=path
|
36
|
-
--log_age=log_age
|
37
|
-
--log_size=log_size
|
38
|
-
-h, --help
|
39
|
-
|
40
|
-
= EXAMPLES
|
41
|
-
|
42
|
-
0) simple usage - just create a file.lock in an atomic fashion
|
43
|
-
|
44
|
-
~ > rlock file.lock
|
45
|
-
|
46
|
-
1) safe usage - create a file.lock, execute a command, and remove file.lock
|
47
|
-
|
48
|
-
~ > rlock file.lock ls file.lock
|
49
|
-
|
50
|
-
2) same as above, but logging verbose messages
|
51
|
-
|
52
|
-
~ > rlock -v4 file.lock ls file.lock
|
53
|
-
|
54
|
-
3) same as above, but logging verbose messages and showing actions internal to
|
55
|
-
lockfile library
|
56
|
-
|
57
|
-
~ > rlock -v4 -d file.lock ls file.lock
|
58
|
-
|
59
|
-
4) same as above
|
60
|
-
|
61
|
-
~ > LOCKFILE_DEBUG=1 rlock -v4 file.lock ls file.lock
|
62
|
-
|
63
|
-
5) same as above
|
64
|
-
|
65
|
-
~ > export LOCKFILE_DEBUG=1
|
66
|
-
~ > rlock -v4 file.lock ls file.lock
|
67
|
-
|
68
|
-
6) note that you need to tell the option parser to stop parsing rlock options if
|
69
|
-
you intend to pass options to 'program'
|
70
|
-
|
71
|
-
~ > rlock -v4 -d file.lock -- ls -ltar file.lock
|
72
|
-
|
73
|
-
without the '--' rlock would consume the '-ltar' options, parsing it
|
74
|
-
as the logfile name 'tar'
|
75
|
-
|
76
|
-
7) lock file.lock and exec 'program' - remove the file.lock if it is older than 4242 seconds
|
77
|
-
|
78
|
-
~ > rlock --max_age=4242 file.lock program
|
79
|
-
|
80
|
-
8) lock file.lock and exec 'program' - remove the file.lock if it is older
|
81
|
-
than 4242 seconds, also spawn a background thread which will refresh
|
82
|
-
file.lock every 8 seonds will 'program' is executing
|
83
|
-
|
84
|
-
~ > rlock --max_age=4242 --refresh=8 file.lock program
|
85
|
-
|
86
|
-
9) same as above, but fail if file.lock cannot be obtained within 1 minute
|
87
|
-
|
88
|
-
~ > rlock --max_age=4242 --refresh=8 --timeout=60 file.lock program
|
data/install.rb
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'rbconfig'
|
3
|
-
require 'find'
|
4
|
-
require 'ftools'
|
5
|
-
require 'tempfile'
|
6
|
-
include Config
|
7
|
-
|
8
|
-
LIBDIR = "lib"
|
9
|
-
LIBDIR_MODE = 0644
|
10
|
-
|
11
|
-
BINDIR = "bin"
|
12
|
-
BINDIR_MODE = 0755
|
13
|
-
|
14
|
-
|
15
|
-
$srcdir = CONFIG["srcdir"]
|
16
|
-
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
17
|
-
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
18
|
-
$archdir = File.join($libdir, CONFIG["arch"])
|
19
|
-
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
20
|
-
$bindir = CONFIG["bindir"]
|
21
|
-
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME']
|
22
|
-
$ruby = File.join($bindir, $ruby_install_name || 'ruby')
|
23
|
-
|
24
|
-
if !$site_libdir
|
25
|
-
$site_libdir = File.join($libdir, "site_ruby")
|
26
|
-
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
27
|
-
$site_libdir = File.join($site_libdir, $version)
|
28
|
-
end
|
29
|
-
|
30
|
-
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
31
|
-
#{{{
|
32
|
-
path = []
|
33
|
-
dir = []
|
34
|
-
Find.find(srcdir) do |f|
|
35
|
-
next unless FileTest.file?(f)
|
36
|
-
next if (f = f[srcdir.length+1..-1]) == nil
|
37
|
-
next if (/CVS$/ =~ File.dirname(f))
|
38
|
-
path.push f
|
39
|
-
dir |= [File.dirname(f)]
|
40
|
-
end
|
41
|
-
for f in dir
|
42
|
-
next if f == "."
|
43
|
-
next if f == "CVS"
|
44
|
-
File::makedirs(File.join(destdir, f))
|
45
|
-
end
|
46
|
-
for f in path
|
47
|
-
next if (/\~$/ =~ f)
|
48
|
-
next if (/^\./ =~ File.basename(f))
|
49
|
-
unless bin
|
50
|
-
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
51
|
-
else
|
52
|
-
from = File.join(srcdir, f)
|
53
|
-
to = File.join(destdir, f)
|
54
|
-
shebangify(from) do |sf|
|
55
|
-
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
56
|
-
$deferr.printf "chmod %04o %s\n", mode, to
|
57
|
-
File::install(sf, to, mode, false)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
#}}}
|
62
|
-
end
|
63
|
-
def shebangify f
|
64
|
-
#{{{
|
65
|
-
open(f) do |fd|
|
66
|
-
buf = fd.read 42
|
67
|
-
if buf =~ %r/^\s*#\s*!.*ruby/o
|
68
|
-
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
69
|
-
begin
|
70
|
-
fd.rewind
|
71
|
-
ftmp.puts "#!#{ $ruby }"
|
72
|
-
while((buf = fd.read(8192)))
|
73
|
-
ftmp.write buf
|
74
|
-
end
|
75
|
-
ftmp.close
|
76
|
-
yield ftmp.path
|
77
|
-
ensure
|
78
|
-
ftmp.close!
|
79
|
-
end
|
80
|
-
else
|
81
|
-
yield f
|
82
|
-
end
|
83
|
-
end
|
84
|
-
#}}}
|
85
|
-
end
|
86
|
-
def ARGV.switch
|
87
|
-
#{{{
|
88
|
-
return nil if self.empty?
|
89
|
-
arg = self.shift
|
90
|
-
return nil if arg == '--'
|
91
|
-
if arg =~ /^-(.)(.*)/
|
92
|
-
return arg if $1 == '-'
|
93
|
-
raise 'unknown switch "-"' if $2.index('-')
|
94
|
-
self.unshift "-#{$2}" if $2.size > 0
|
95
|
-
"-#{$1}"
|
96
|
-
else
|
97
|
-
self.unshift arg
|
98
|
-
nil
|
99
|
-
end
|
100
|
-
#}}}
|
101
|
-
end
|
102
|
-
def ARGV.req_arg
|
103
|
-
#{{{
|
104
|
-
self.shift || raise('missing argument')
|
105
|
-
#}}}
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
#
|
110
|
-
# main program
|
111
|
-
#
|
112
|
-
|
113
|
-
libdir = $site_libdir
|
114
|
-
bindir = $bindir
|
115
|
-
|
116
|
-
begin
|
117
|
-
while switch = ARGV.switch
|
118
|
-
case switch
|
119
|
-
when '-d', '--destdir'
|
120
|
-
libdir = ARGV.req_arg
|
121
|
-
when '-l', '--libdir'
|
122
|
-
libdir = ARGV.req_arg
|
123
|
-
when '-b', '--bindir'
|
124
|
-
bindir = ARGV.req_arg
|
125
|
-
when '-r', '--ruby'
|
126
|
-
$ruby = ARGV.req_arg
|
127
|
-
else
|
128
|
-
raise "unknown switch #{switch.dump}"
|
129
|
-
end
|
130
|
-
end
|
131
|
-
rescue
|
132
|
-
STDERR.puts $!.to_s
|
133
|
-
STDERR.puts File.basename($0) +
|
134
|
-
" -d <destdir>" +
|
135
|
-
" -l <libdir>" +
|
136
|
-
" -b <bindir>"
|
137
|
-
" -r <ruby>"
|
138
|
-
exit 1
|
139
|
-
end
|
140
|
-
|
141
|
-
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
142
|
-
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
143
|
-
|