Module: Lifeline
- Defined in:
- lib/lifeline.rb
Defined Under Namespace
Classes: LifelineRakeTask
Instance Method Summary collapse
-
#define_lifeline_tasks(namespace, &block) ⇒ Object
A method that defines 3 rake tasks for doing lifelines: *
namespace:run
runs the specified block *namespace:lifeline
a lifeline for executing only a single copy ofnamespace:run
at a time *namespace:terminate
a task for terminating the lifelines. - #get_process_list ⇒ Object
- #get_processes_from_shell ⇒ Object
-
#lifeline ⇒ Object
A method for executing a block of code only if there is no other process with the same command running.
Instance Method Details
#define_lifeline_tasks(namespace, &block) ⇒ Object
A method that defines 3 rake tasks for doing lifelines:
-
namespace:run
runs the specified block -
namespace:lifeline
a lifeline for executing only a single copy ofnamespace:run
at a time -
namespace:terminate
a task for terminating the lifelines
135 136 137 |
# File 'lib/lifeline.rb', line 135 def define_lifeline_tasks(namespace, &block) LifelineRakeTask.new(namespace, &block) end |
#get_process_list ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/lifeline.rb', line 13 def get_process_list processes = get_processes_from_shell return nil if processes.nil? processes.split(/\n/).map do |p| if p =~ /^\s*(\d+)\s(.+)$/ {:pid => $1.to_i, :command => $2.strip} end end.compact end |
#get_processes_from_shell ⇒ Object
7 8 9 |
# File 'lib/lifeline.rb', line 7 def get_processes_from_shell %x{ps ax -o pid,command} end |
#lifeline ⇒ Object
A method for executing a block of code only if there is no other process with the same command running. This is useful if you want to have a perpetually running daemon that only executes once at a time. It uses the process name returned by ps ax to see if there is a process with the same command name but a different PID already executing. If so, it terminates without running the block. NOTE: since it uses the command name returned from ps ax
, it us up to to you to name the process containing this code with a distinctly unique name. If two separate Rails projects both have a rake lifeline
task they WILL interfere with each other. I’d suggest prefixing with the project name (ie, doc_viewer:lifeline
) to be sure
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/lifeline.rb', line 35 def lifeline if !block_given? raise ArgumentError, "You must pass in a block to be the body of the run rake task" end my_pid = $$ processes = get_process_list if processes.nil? || processes.empty? raise "No processes being returned by get_process_list. Aborting!" end myself = processes.detect {|p| p[:pid] == my_pid} if myself.nil? raise "Unable to find self (PID=#{my_pid}) in process list. This is bizarre to say the least. Exiting.\n#{processes.map {|p| p.inspect}.join("\n")}" end # there isn't already another process running with the same command if !processes.any? {|p| p[:pid] != my_pid && p[:command] == myself[:command]} yield end end |