pidlock 0.0.2

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/README.mkd ADDED
@@ -0,0 +1,24 @@
1
+ # Pidlock
2
+
3
+ [![Build Status](https://secure.travis-ci.org/abangratz/pidlock.png)](http://travis-ci.org/abangratz/pidlock)
4
+
5
+ This is a ruby library for using pid-file based locking of programs/daemons to prevent multiple parallel running tasks.
6
+
7
+ ## Prerequisites
8
+
9
+ The gem ``sys/proctable`` is required.
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ require 'sys/proctable'
15
+
16
+ Pidlock.new('my.pid').lock # tries to create a lock file '/var/run/my.pid';
17
+ # raises an error if the file is locked or a program exists that
18
+ # has the same basename and pid (here: 'my')
19
+ ...
20
+ ```
21
+
22
+ ## TODO
23
+
24
+ Lots still. First release.
data/lib/pidlock.rb ADDED
@@ -0,0 +1,31 @@
1
+ class Pidlock
2
+
3
+
4
+ class FileLockedException < Exception; end
5
+ class ProcessRunning < Exception; end
6
+ def initialize(name)
7
+ @name = File.basename(name)
8
+ @filename = File.join('/', 'var', 'run', @name)
9
+ end
10
+
11
+ def lock
12
+ unless @file
13
+ unless (File.writable?(File.dirname(@filename)))
14
+ @filename = File.join('/', 'tmp', @name)
15
+ end
16
+ @file = File.open(@filename, 'w+')
17
+ if (old_pid = @file.gets)
18
+ if (old_process = Sys::ProcTable.ps(old_pid.chomp.to_i))
19
+ raise ProcessRunning if old_process.comm == File.basename(@name, File.extname(@name))
20
+ else
21
+ STDERR.puts "WARNING: resetting stale lockfile"
22
+ @file.rewind
23
+ end
24
+ end
25
+ @file.flock(File::LOCK_EX | File::LOCK_NB) or raise FileLockedException
26
+ @file.write Process.pid
27
+ @file.flush
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pidlock do
4
+ before(:each) do
5
+ @file = stub(File)
6
+ @file.stub(:flock)
7
+ @file.stub(:write)
8
+ @file.stub(:flock => 0)
9
+ @file.stub(:flush)
10
+ @file.stub(:gets)
11
+ File.stub(:open).with('/var/run/my.pid', 'w+').and_return(@file)
12
+ File.stub(:writable?).with('/var/run').and_return(true)
13
+ end
14
+ it "should create a file with the given name in /var/run" do
15
+ Pidlock.new('my.pid').lock
16
+ end
17
+ context "filehandling" do
18
+ before(:each) do
19
+ Process.stub(:pid).and_return(666)
20
+ end
21
+ it "should write the current pid to the file" do
22
+ @file.should_receive(:write).with(666)
23
+ Pidlock.new('my.pid').lock
24
+ end
25
+
26
+ it "should try to lock the file" do
27
+ @file.should_receive(:flock).with( File::LOCK_EX | File::LOCK_NB).and_return(0)
28
+ Pidlock.new('my.pid').lock
29
+ end
30
+
31
+ it "should raise if the lock does not succeed" do
32
+ @file.should_receive(:flock).with( File::LOCK_EX | File::LOCK_NB).and_return(false)
33
+ lambda {
34
+ Pidlock.new('my.pid').lock
35
+ }.should raise_error Pidlock::FileLockedException
36
+ end
37
+
38
+ it "should check if the program name matches the id" do
39
+ @file.should_receive(:gets).and_return('666')
40
+ ps = stub("ProcTableStruct", :comm => 'test')
41
+ ::Sys::ProcTable.should_receive(:ps).with(666).and_return(ps)
42
+ Pidlock.new('my.pid').lock
43
+ end
44
+ it "should raise if the program name does match the pid" do
45
+ @file.should_receive(:gets).and_return('666')
46
+ ps = stub("ProcTableStruct", :comm => 'my')
47
+ ::Sys::ProcTable.should_receive(:ps).with(666).and_return(ps)
48
+ lambda {
49
+ Pidlock.new('my.pid').lock
50
+ }.should raise_error Pidlock::ProcessRunning
51
+ end
52
+
53
+ it "should use /tmp if /var/run is not writeable" do
54
+ File.should_receive(:writable?).with('/var/run').and_return(false)
55
+ File.should_receive(:open).with('/tmp/my.pid', 'w+').and_return(@file)
56
+ Pidlock.new('my.pid').lock
57
+
58
+ end
59
+ it "should warn but continue if the file exists but the process name does not" do
60
+ @file.should_receive(:gets).and_return('667')
61
+ ps = stub("ProcTableStruct", :comm => 'test')
62
+ ::Sys::ProcTable.should_receive(:ps).with(667).and_return(nil)
63
+ STDERR.should_receive(:puts).with('WARNING: resetting stale lockfile')
64
+ @file.should_receive(:rewind)
65
+ @file.should_receive(:write).with(666)
66
+ Pidlock.new('my.pid').lock
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,8 @@
1
+ $: << '.'
2
+ require 'bundler/setup'
3
+ Bundler.setup(:default, :development)
4
+ require 'stringio'
5
+
6
+ require 'sys/proctable'
7
+ require 'lib/pidlock'
8
+
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pidlock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Anton Bangratz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-28 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sys-proctable
16
+ requirement: &16613480 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *16613480
25
+ description: Used for locking processes via PID and file (daemon style).
26
+ email: anton.bangratz@gmail.com
27
+ executables: []
28
+ extensions: []
29
+ extra_rdoc_files:
30
+ - README.mkd
31
+ files:
32
+ - lib/pidlock.rb
33
+ - spec/lib/pidlock_spec.rb
34
+ - spec/spec_helper.rb
35
+ - README.mkd
36
+ homepage: https://github.com/abangratz/pidlock
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.10
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Using PID/file locking for daemons and long running tasks made easy.
60
+ test_files: []