Class: Spawn
- Inherits:
-
Object
- Object
- Spawn
- Defined in:
- lib/spawn.rb
Constant Summary collapse
- RAILS_1_x =
nil
- RAILS_2_2 =
nil
- RAILS_3_x =
nil
- @@default_options =
{ # default to forking (unless windows or jruby) :method => ((RUBY_PLATFORM =~ /(win32|mingw32|java)/) ? :thread : :fork), :nice => nil, :kill => false, :argv => nil }
- @@resources =
things to close in child process
[]
- @@punks =
forked children to kill on exit
[]
- @@logger =
in some environments, logger isn’t defined
defined?(::Rails) ? ::Rails.logger : ::Logger.new(STDERR)
Instance Attribute Summary collapse
-
#handle ⇒ Object
Returns the value of attribute handle.
-
#type ⇒ Object
Returns the value of attribute type.
Class Method Summary collapse
- .alive?(pid) ⇒ Boolean
-
.close_resources ⇒ Object
close all the resources added by calls to resource_to_close.
-
.default_options(options = {}) ⇒ Object
Set the options to use every time spawn is called unless specified otherwise.
- .kill_punks ⇒ Object
-
.resources_to_close(*resources) ⇒ Object
set the resources to disconnect from in the child process (when forking).
- .wait(sids = []) ⇒ Object
Instance Method Summary collapse
-
#initialize(opts = {}) ⇒ Spawn
constructor
Spawns a long-running section of code and returns the ID of the spawned process.
Constructor Details
#initialize(opts = {}) ⇒ Spawn
Spawns a long-running section of code and returns the ID of the spawned process. By default the process will be a forked process. To use threading, pass :method => :thread or override the default behavior in the environment by setting ‘Spawn::method :thread’.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/spawn.rb', line 93 def initialize(opts = {}) raise "Must give block of code to be spawned" unless block_given? = @@default_options.merge((opts)) # setting options[:method] will override configured value in default_options[:method] if [:method] == :yield yield elsif [:method].respond_to?(:call) [:method].call(proc { yield }) elsif [:method] == :thread # for versions before 2.2, check for allow_concurrency if RAILS_2_2 || ActiveRecord::Base.respond_to?(:allow_concurrency) ? ActiveRecord::Base.allow_concurrency : Rails.application.config.allow_concurrency @type = :thread @handle = thread_it() { yield } else @@logger.error("spawn(:method=>:thread) only allowed when allow_concurrency=true") raise "spawn requires config.active_record.allow_concurrency=true when used with :method=>:thread" end else @type = :fork @handle = fork_it() { yield } end end |
Instance Attribute Details
#handle ⇒ Object
Returns the value of attribute handle.
32 33 34 |
# File 'lib/spawn.rb', line 32 def handle @handle end |
#type ⇒ Object
Returns the value of attribute type.
31 32 33 |
# File 'lib/spawn.rb', line 31 def type @type end |
Class Method Details
.alive?(pid) ⇒ Boolean
64 65 66 67 68 69 70 71 72 |
# File 'lib/spawn.rb', line 64 def self.alive?(pid) begin Process::kill 0, pid # if the process is alive then kill won't throw an exception true rescue Errno::ESRCH false end end |
.close_resources ⇒ Object
close all the resources added by calls to resource_to_close
56 57 58 59 60 61 62 |
# File 'lib/spawn.rb', line 56 def self.close_resources @@resources.each do |resource| resource.close if resource && resource.respond_to?(:close) && !resource.closed? end # in case somebody spawns recursively @@resources.clear end |
.default_options(options = {}) ⇒ Object
Set the options to use every time spawn is called unless specified otherwise. For example, in your environment, do something like this:
Spawn:: = {:nice => 5}
to default to using the :nice option with a value of 5 on every call. Valid options are:
:method => (:thread | :fork | :yield)
:nice => nice value of the forked process
:kill => whether or not the parent process will kill the
spawned child process when the parent exits
:argv => changes name of the spawned process as seen in ps
45 46 47 48 |
# File 'lib/spawn.rb', line 45 def self.( = {}) @@default_options.merge!() @@logger.info "spawn> default options = #{.inspect}" if @@logger end |
.kill_punks ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/spawn.rb', line 74 def self.kill_punks @@punks.each do |punk| if alive?(punk) @@logger.info "spawn> parent(#{Process.pid}) killing child(#{punk})" if @@logger begin Process.kill("TERM", punk) rescue end end end @@punks = [] end |
.resources_to_close(*resources) ⇒ Object
set the resources to disconnect from in the child process (when forking)
51 52 53 |
# File 'lib/spawn.rb', line 51 def self.resources_to_close(*resources) @@resources = resources end |
.wait(sids = []) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/spawn.rb', line 117 def self.wait(sids = []) # wait for all threads and/or forks (if a single sid passed in, convert to array first) Array(sids).each do |sid| if sid.type == :thread sid.handle.join() else begin Process.wait(sid.handle) rescue # if the process is already done, ignore the error end end end # clean up connections from expired threads ActiveRecord::Base.verify_active_connections!() if defined?(ActiveRecord) end |