Module: Spawn
- Defined in:
- lib/spawn.rb
Defined Under Namespace
Classes: SpawnId
Constant Summary
- RAILS_1_x =
(::Rails::VERSION::MAJOR == 1)
- RAILS_2_2 =
((::Rails::VERSION::MAJOR == 2 && ::Rails::VERSION::MINOR >= 2))
- RAILS_3_x =
(::Rails::VERSION::MAJOR > 2)
- @@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
[]
Class Method Summary (collapse)
- + (Boolean) alive?(pid)
-
+ (Object) close_resources
close all the resources added by calls to resource_to_close.
-
+ (Object) default_options(options = {})
Set the options to use every time spawn is called unless specified otherwise.
-
+ (Object) included(klazz)
Make sure we have a logger and require our patches when we're included.
- + (Object) kill_punks
-
+ (Object) resources_to_close(*resources)
set the resources to disconnect from in the child process (when forking).
Instance Method Summary (collapse)
-
- (Object) spawn(opts = {})
Spawns a long-running section of code and returns the ID of the spawned process.
- - (Object) wait(sids = [])
Class Method Details
+ (Boolean) alive?(pid)
59 60 61 62 63 64 65 66 67 |
# File 'lib/spawn.rb', line 59 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 |
+ (Object) close_resources
close all the resources added by calls to resource_to_close
51 52 53 54 55 56 57 |
# File 'lib/spawn.rb', line 51 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 |
+ (Object) default_options(options = {})
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
40 41 42 43 |
# File 'lib/spawn.rb', line 40 def self.( = {}) @@default_options.merge!() @@logger.info "spawn> default options = #{.inspect}" if @@logger end |
+ (Object) included(klazz)
Make sure we have a logger and require our patches when we're included
22 23 24 25 26 |
# File 'lib/spawn.rb', line 22 def self.included(klazz) # in some environments, logger isn't defined @@logger = defined?(Rails) ? Rails.logger : Logger.new(STDERR) require 'patches' end |
+ (Object) kill_punks
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/spawn.rb', line 69 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 |
+ (Object) resources_to_close(*resources)
set the resources to disconnect from in the child process (when forking)
46 47 48 |
# File 'lib/spawn.rb', line 46 def self.resources_to_close(*resources) @@resources = resources end |
Instance Method Details
- (Object) spawn(opts = {})
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'.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/spawn.rb', line 113 def spawn(opts = {}) = @@default_options.merge(opts.symbolize_keys) # 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 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 fork_it() { yield } end end |
- (Object) wait(sids = [])
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/spawn.rb', line 134 def 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!() end |