Class: ScoutAgent::IDCard
- Inherits:
-
Object
- Object
- ScoutAgent::IDCard
- Defined in:
- lib/scout_agent/id_card.rb
Overview
This class excapsulates a named process. It is used to ensure exclusive execution and to signal other processes.
Instance Attribute Summary collapse
-
#process_name ⇒ Object
readonly
Returns the value of attribute process_name.
Class Method Summary collapse
-
.me ⇒ Object
This global attribute should contain the IDCard for this process.
-
.me=(id_card) ⇒ Object
A setter for the identity of this process.
Instance Method Summary collapse
-
#authorize(&block) ⇒ Object
Claims this identity for this process.
-
#initialize(process_name) ⇒ IDCard
constructor
Pass in the
process_name
of the process you want to signal() or theprocess_name
you wish to authorize() for yourself. -
#pid ⇒ Object
Returns the PID for the named process or
nil
if it cannot be read. -
#pid_file ⇒ Object
Returns the path to the unique PID file for this process, based on the current Plan.
-
#revoke ⇒ Object
Releases a held claim on a process name.
-
#signal(message) ⇒ Object
Tries to send
message
as a signal to the process represented by this instance. -
#to_s ⇒ Object
A String representation of this process, with PID.
Constructor Details
#initialize(process_name) ⇒ IDCard
Pass in the process_name
of the process you want to signal() or the process_name
you wish to authorize() for yourself.
36 37 38 |
# File 'lib/scout_agent/id_card.rb', line 36 def initialize(process_name) @process_name = process_name end |
Instance Attribute Details
#process_name ⇒ Object (readonly)
Returns the value of attribute process_name.
40 41 42 |
# File 'lib/scout_agent/id_card.rb', line 40 def process_name @process_name end |
Class Method Details
.me ⇒ Object
This global attribute should contain the IDCard for this process. It is set during a successful authorization.
Warning: Be sure to clear this attribute immediately after a fork(), with a call to me=(), so you don’t keep the parent’s identity.
17 18 19 |
# File 'lib/scout_agent/id_card.rb', line 17 def self.me @me ||= nil end |
.me=(id_card) ⇒ Object
A setter for the identity of this process. This is set automatically as part of an authorization.
Warning: Be sure to clear this attribute immediately after a fork() so you don’t keep the parent’s identity.
28 29 30 |
# File 'lib/scout_agent/id_card.rb', line 28 def self.me=(id_card) @me = id_card end |
Instance Method Details
#authorize(&block) ⇒ Object
Claims this identity for this process. This process is multiprocess-safe and will fail if another process has claimed this identity. However, stale claims are ignored and replaced, if possible.
This method returns true
in the claim succeeded and false
if it could not happen for any reason. A return of true
indicates that IDCard::me()
has been updated and an exit handle has been installed to revoke() this claim as the process ends.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/scout_agent/id_card.rb', line 90 def (&block) File.open(pid_file, File::CREAT | File::EXCL | File::WRONLY) do |pid| pid.flock(File::LOCK_EX) if block.nil? or block.call # allows for daemonization pid.puts Process.pid else pid.flock(File::LOCK_UN) revoke # remove this file if anything went wrong return false end pid.flock(File::LOCK_UN) end self.class.me = self at_my_exit do revoke end true rescue Errno::EEXIST # pid_file already exists File.open(pid_file, "r+") do |pid| if pid.flock(File::LOCK_EX | File::LOCK_NB) if pid.read =~ /\A\d+/ begin signal(0) # check for the existing process rescue Errno::ESRCH # no such process # stale PID file found, clearing it and reloading if revoke pid.flock(File::LOCK_UN) # release the lock before we recurse return (&block) # try again end rescue Errno::EACCES # don't have permission # nothing we can do so give up end end pid.flock(File::LOCK_UN) # release the lock else # couldn't grab a file lock to verify existing PID file return false end end # process was already running false end |
#pid ⇒ Object
Returns the PID for the named process or nil
if it cannot be read.
56 57 58 59 60 |
# File 'lib/scout_agent/id_card.rb', line 56 def pid pid_file.read.to_i rescue Exception # cannot read file nil end |
#pid_file ⇒ Object
Returns the path to the unique PID file for this process, based on the current Plan.
51 52 53 |
# File 'lib/scout_agent/id_card.rb', line 51 def pid_file Plan.pid_dir + "#{@process_name}.pid" end |
#revoke ⇒ Object
Releases a held claim on a process name. Returns true
if successful or false
if the PID file didn’t exist or couldn’t be destroyed.
139 140 141 142 143 144 |
# File 'lib/scout_agent/id_card.rb', line 139 def revoke pid_file.unlink true rescue Exception false end |
#signal(message) ⇒ Object
Tries to send message
as a signal to the process represented by this instance. You can pass any message Process.kill()
would understand.
Returns true
if the signal was sent, or false
if the PID file could not be read. Any Exception raised during the send, such as Errno::ESRCH for a missing process, will bubble up to the calling code.
71 72 73 74 75 76 77 78 |
# File 'lib/scout_agent/id_card.rb', line 71 def signal() if id = pid Process.kill(, id) true else false end end |
#to_s ⇒ Object
A String representation of this process, with PID.
43 44 45 |
# File 'lib/scout_agent/id_card.rb', line 43 def to_s "#{@process_name} (#{pid || 'unauthorized'})" end |