pidfile 0.2.0 → 0.3.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.
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