pidfile 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.rdoc +15 -4
  2. data/lib/pidfile.rb +39 -13
  3. metadata +9 -4
@@ -17,15 +17,14 @@ Install the pidfile gem:
17
17
 
18
18
  == Gettings Started
19
19
 
20
- The pidfile gem is easy to use and only requires the addition of a single line
21
- of code; something like this:
20
+ The pidfile gem is easy to use and only requires the instantiation of the
21
+ pidfile, like so:
22
22
 
23
- pf = PidFile.new unless PidFile.running?
23
+ pf = PidFile.new
24
24
 
25
25
  Of course there is other functionality, but if you are just wanting to keep a
26
26
  process from running more than once, this is all you need.
27
27
 
28
-
29
28
  === Arguments
30
29
 
31
30
  PidFile creates file to store the process ID (PID). By default, process ID
@@ -40,6 +39,18 @@ class.
40
39
 
41
40
  PidFile.new(:piddir => '/var/lock', :pidfile => "awesome.pid")
42
41
 
42
+ == Miscellaneous
43
+
44
+ === Why isn't this a singleton?
45
+
46
+ My main concern is how it would behave when a process is forked multiple times.
47
+ Each new process would get its own PID, but I wasn't sure how using a singleton
48
+ would affect this; if the interrelationship of the processes would keep the
49
+ object from correctly identifying the correct pidfile.
50
+
51
+ Anyway, I like the flexibility that not using a singleton offers, and I guess
52
+ I'd rather ask you not to do something bad rather than restraining you.
53
+
43
54
  == Copyright
44
55
 
45
56
  Copyright(c) 2010 Samuel Mullen (samullen). See LICENSE for details
@@ -1,7 +1,9 @@
1
1
  class PidFile
2
- attr_accessor :pidfile, :piddir
2
+ attr_reader :pidfile, :piddir, :pidpath
3
3
 
4
- VERSION = '0.2.0'
4
+ class DuplicateProcessError < RuntimeError; end
5
+
6
+ VERSION = '0.3.0'
5
7
 
6
8
  DEFAULT_OPTIONS = {
7
9
  :pidfile => File.basename($0, File.extname($0)) + ".pid",
@@ -11,6 +13,7 @@ class PidFile
11
13
  def initialize(*args)
12
14
  opts = {}
13
15
 
16
+ #----- set options -----#
14
17
  case
15
18
  when args.length == 0 then
16
19
  when args.length == 1 && args[0].class == Hash then
@@ -27,17 +30,29 @@ class PidFile
27
30
 
28
31
  @piddir = opts[:piddir]
29
32
  @pidfile = opts[:pidfile]
33
+ @pidpath = File.join(@piddir, @pidfile)
30
34
  @fh = nil
31
35
 
36
+ #----- Does the pidfile or pid exist? -----#
37
+ if self.pidfile_exists?
38
+ if self.class.running?(@pidpath)
39
+ raise DuplicateProcessError, "Process (#{$0} - #{self.class.pid(@pidpath)}) is already running."
40
+
41
+ exit! # exit without removing the existing pidfile
42
+ end
43
+
44
+ self.release
45
+ end
46
+
47
+ #----- create the pidfile -----#
32
48
  create_pidfile
33
49
 
34
50
  at_exit { release }
35
51
  end
36
52
 
37
- # Returns the fullpath to the file containing the process ID (PID)
38
- def pidpath
39
- File.join(@piddir, @pidfile)
40
- end
53
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
54
+ # Instance Methods
55
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
41
56
 
42
57
  # Returns the PID, if any, of the instantiating process
43
58
  def pid
@@ -76,6 +91,17 @@ class PidFile
76
91
  File.mtime(self.pidpath)
77
92
  end
78
93
 
94
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
95
+ # Class Methods
96
+ #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
97
+
98
+ # Returns the PID, if any, of the instantiating process
99
+ def self.pid(path=nil)
100
+ if pidfile_exists?(path)
101
+ open(path, 'r').read.to_i
102
+ end
103
+ end
104
+
79
105
  # class method for determining the existence of pidfile
80
106
  def self.pidfile_exists?(path=nil)
81
107
  path ||= File.join(DEFAULT_OPTIONS[:piddir], DEFAULT_OPTIONS[:pidfile])
@@ -85,30 +111,30 @@ class PidFile
85
111
 
86
112
  # boolean stating whether the calling program is already running
87
113
  def self.running?(path=nil)
114
+ calling_pid = nil
88
115
  path ||= File.join(DEFAULT_OPTIONS[:piddir], DEFAULT_OPTIONS[:pidfile])
89
116
 
90
117
  if pidfile_exists?(path)
91
- pid = open(path, 'r').read.to_i
92
- else
93
- pid = nil
118
+ calling_pid = pid(path)
94
119
  end
95
120
 
96
- return false unless pid && (pid != Process.pid)
97
-
98
- process_exists?(pid)
121
+ process_exists?(calling_pid)
99
122
  end
100
123
 
101
124
  private
102
125
 
103
126
  # Writes the process ID to the pidfile and defines @pid as such
104
127
  def create_pidfile
128
+ # Once the filehandle is created, we don't release until the process dies.
105
129
  @fh = open(self.pidpath, "w")
106
130
  @fh.flock(File::LOCK_EX | File::LOCK_NB) || raise
107
131
  @pid = Process.pid
108
132
  @fh.puts @pid
133
+ @fh.flush
134
+ @fh.rewind
109
135
  end
110
136
 
111
- # removes the pidfile.
137
+ # removes the pidfile.
112
138
  def remove_pidfile
113
139
  File.unlink(self.pidpath) if self.pidfile_exists?
114
140
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pidfile
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 19
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 2
8
+ - 3
8
9
  - 0
9
- version: 0.2.0
10
+ version: 0.3.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Samuel Mullen
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-06-14 00:00:00 -05:00
18
+ date: 2010-07-27 00:00:00 -05:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -41,23 +42,27 @@ rdoc_options: []
41
42
  require_paths:
42
43
  - lib
43
44
  required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
44
46
  requirements:
45
47
  - - ">="
46
48
  - !ruby/object:Gem::Version
49
+ hash: 3
47
50
  segments:
48
51
  - 0
49
52
  version: "0"
50
53
  required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
51
55
  requirements:
52
56
  - - ">="
53
57
  - !ruby/object:Gem::Version
58
+ hash: 3
54
59
  segments:
55
60
  - 0
56
61
  version: "0"
57
62
  requirements: []
58
63
 
59
64
  rubyforge_project:
60
- rubygems_version: 1.3.6
65
+ rubygems_version: 1.3.7
61
66
  signing_key:
62
67
  specification_version: 3
63
68
  summary: A basic library for creating lockfiles for processes