spawnling 2.1 → 2.1.1
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.
- data/README.md +18 -14
- data/init.rb +1 -1
- data/lib/patches.rb +9 -9
- data/lib/{spawn.rb → spawnling.rb} +9 -8
- data/lib/{spawn → spawnling}/cucumber.rb +0 -0
- metadata +32 -36
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
#News
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
2013-4-15 gem renamed from "spawn-block" (lame) to "spawnling" (awesome). Sadly the
|
4
|
+
name "spawn" was taken before I got around to making this into a gem so I decided to
|
5
|
+
give it a new name and a new home.
|
6
|
+
|
7
|
+
Also, now runs with ruby 1.9 (and later). Because ruby "stole" the name "spawn", this gem
|
8
|
+
now has been redefined to use "Spawnling.new(&block)" instead of "spawn(&block)". Other
|
5
9
|
than that nothing has changed in the basic usage. Read below for detailed usage.
|
6
10
|
|
7
|
-
#
|
11
|
+
# Spawnling
|
8
12
|
|
9
|
-
This gem provides a '
|
13
|
+
This gem provides a 'Spawnling' class to easily fork OR thread long-running sections of
|
10
14
|
code so that your application can return results to your users more quickly.
|
11
15
|
It works by creating new database connections in ActiveRecord::Base for the
|
12
16
|
spawned block so that you don't have to worry about database connections working,
|
@@ -50,7 +54,7 @@ into your config/database.yml.
|
|
50
54
|
Here's a simple example of how to demonstrate the spawn plugin.
|
51
55
|
In one of your controllers, insert this code (after installing the plugin of course):
|
52
56
|
```ruby
|
53
|
-
|
57
|
+
Spawnling.new do
|
54
58
|
logger.info("I feel sleepy...")
|
55
59
|
sleep 11
|
56
60
|
logger.info("Time to wake up!")
|
@@ -60,17 +64,17 @@ If everything is working correctly, your controller should finish quickly then y
|
|
60
64
|
the last log message several seconds later.
|
61
65
|
|
62
66
|
If you need to wait for the spawned processes/threads, then pass the objects returned by
|
63
|
-
spawn to
|
67
|
+
spawn to Spawnling.wait(), like this:
|
64
68
|
```ruby
|
65
69
|
spawns = []
|
66
70
|
N.times do |i|
|
67
71
|
# spawn N blocks of code
|
68
|
-
spawns <<
|
72
|
+
spawns << Spawnling.new do
|
69
73
|
something(i)
|
70
74
|
end
|
71
75
|
end
|
72
76
|
# wait for all N blocks of code to finish running
|
73
|
-
|
77
|
+
Spawnling.wait(spawns)
|
74
78
|
```
|
75
79
|
## Options
|
76
80
|
|
@@ -89,7 +93,7 @@ Any option to spawn can be set as a default so that you don't have to pass them
|
|
89
93
|
to every call of spawn. To configure the spawn default options, add a line to
|
90
94
|
your configuration file(s) like this:
|
91
95
|
```ruby
|
92
|
-
|
96
|
+
Spawnling.default_options {:method => :thread}
|
93
97
|
```
|
94
98
|
If you don't set any default options, the :method will default to :fork. To
|
95
99
|
specify different values for different environments, add the default_options call to
|
@@ -97,9 +101,9 @@ he appropriate environment file (development.rb, test.rb). For testing you can
|
|
97
101
|
the default :method to :yield so that the code is run inline.
|
98
102
|
```ruby
|
99
103
|
# in environment.rb
|
100
|
-
|
104
|
+
Spawnling.method :method => :fork, :nice => 7
|
101
105
|
# in test.rb, will override the environment.rb setting
|
102
|
-
|
106
|
+
Spawnling.method :method => :yield
|
103
107
|
```
|
104
108
|
This allows you to set your production and development environments to use different
|
105
109
|
methods according to your needs.
|
@@ -109,7 +113,7 @@ methods according to your needs.
|
|
109
113
|
If you want your forked child to run at a lower priority than the parent process, pass in
|
110
114
|
the :nice option like this:
|
111
115
|
```ruby
|
112
|
-
|
116
|
+
Spawnling.new(:nice => 7) do
|
113
117
|
do_something_nicely
|
114
118
|
end
|
115
119
|
```
|
@@ -120,7 +124,7 @@ do threading either by telling the spawn method when you call it or by configuri
|
|
120
124
|
environment.
|
121
125
|
For example, this is how you can tell spawn to use threading on the call,
|
122
126
|
```ruby
|
123
|
-
|
127
|
+
Spawnling.new(:method => :thread) do
|
124
128
|
something
|
125
129
|
end
|
126
130
|
```
|
@@ -149,7 +153,7 @@ listing the running processes (ps).
|
|
149
153
|
For example, if you do something like this,
|
150
154
|
```ruby
|
151
155
|
3.times do |i|
|
152
|
-
|
156
|
+
Spawnling.new(:argv => "spawn -#{i}-") do
|
153
157
|
something(i)
|
154
158
|
end
|
155
159
|
end
|
data/init.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require 'spawnling'
|
data/lib/patches.rb
CHANGED
@@ -2,7 +2,7 @@ if defined?(ActiveRecord)
|
|
2
2
|
# see activerecord/lib/active_record/connection_adaptors/abstract/connection_specification.rb
|
3
3
|
class ActiveRecord::Base
|
4
4
|
# reconnect without disconnecting
|
5
|
-
if ::
|
5
|
+
if ::Spawnling::RAILS_3_x || ::Spawnling::RAILS_2_2
|
6
6
|
def self.spawn_reconnect(klass=self)
|
7
7
|
# keep ancestors' connection_handlers around to avoid them being garbage collected in the forked child
|
8
8
|
@@ancestor_connection_handlers ||= []
|
@@ -24,7 +24,7 @@ if defined?(ActiveRecord)
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# this patch not needed on Rails 2.x and later
|
27
|
-
if ::
|
27
|
+
if ::Spawnling::RAILS_1_x
|
28
28
|
# monkey patch to fix threading problems,
|
29
29
|
# see: http://dev.rubyonrails.org/ticket/7579
|
30
30
|
def self.clear_reloadable_connections!
|
@@ -58,7 +58,7 @@ if defined?(Unicorn::HttpServer) && defined?(Unicorn::HttpRequest::REQ)
|
|
58
58
|
REQ = Unicorn::HttpRequest::REQ
|
59
59
|
alias_method :orig_process_client, :process_client
|
60
60
|
def process_client(client)
|
61
|
-
::
|
61
|
+
::Spawnling.resources_to_close(client, REQ)
|
62
62
|
orig_process_client(client)
|
63
63
|
end
|
64
64
|
end
|
@@ -66,7 +66,7 @@ elsif defined? Unicorn::HttpServer
|
|
66
66
|
class Unicorn::HttpServer
|
67
67
|
alias_method :orig_process_client, :process_client
|
68
68
|
def process_client(client)
|
69
|
-
::
|
69
|
+
::Spawnling.resources_to_close(client, @request)
|
70
70
|
orig_process_client(client)
|
71
71
|
end
|
72
72
|
end
|
@@ -78,10 +78,10 @@ end
|
|
78
78
|
if defined? Mongrel::HttpServer
|
79
79
|
class Mongrel::HttpServer
|
80
80
|
# redefine Montrel::HttpServer::process_client so that we can intercept
|
81
|
-
# the socket that is being used so
|
81
|
+
# the socket that is being used so Spawnling can close it upon forking
|
82
82
|
alias_method :orig_process_client, :process_client
|
83
83
|
def process_client(client)
|
84
|
-
::
|
84
|
+
::Spawnling.resources_to_close(client, @socket)
|
85
85
|
orig_process_client(client)
|
86
86
|
end
|
87
87
|
end
|
@@ -101,7 +101,7 @@ if need_passenger_patch
|
|
101
101
|
class Passenger::Railz::RequestHandler
|
102
102
|
alias_method :orig_process_request, :process_request
|
103
103
|
def process_request(headers, input, output)
|
104
|
-
::
|
104
|
+
::Spawnling.resources_to_close(input, output)
|
105
105
|
orig_process_request(headers, input, output)
|
106
106
|
end
|
107
107
|
end
|
@@ -112,7 +112,7 @@ if need_passenger_patch
|
|
112
112
|
class PhusionPassenger::Railz::RequestHandler
|
113
113
|
alias_method :orig_process_request, :process_request
|
114
114
|
def process_request(headers, input, output)
|
115
|
-
::
|
115
|
+
::Spawnling.resources_to_close(input, output)
|
116
116
|
orig_process_request(headers, input, output)
|
117
117
|
end
|
118
118
|
end
|
@@ -123,7 +123,7 @@ if need_passenger_patch
|
|
123
123
|
class PhusionPassenger::Rack::RequestHandler
|
124
124
|
alias_method :orig_process_request, :process_request
|
125
125
|
def process_request(headers, input, output)
|
126
|
-
::
|
126
|
+
::Spawnling.resources_to_close(input, output)
|
127
127
|
orig_process_request(headers, input, output)
|
128
128
|
end
|
129
129
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
|
-
class
|
3
|
+
class Spawnling
|
4
4
|
if defined? ::Rails
|
5
5
|
RAILS_1_x = (::Rails::VERSION::MAJOR == 1) unless defined?(RAILS_1_x)
|
6
6
|
RAILS_2_2 = ((::Rails::VERSION::MAJOR == 2 && ::Rails::VERSION::MINOR >= 2)) unless defined?(RAILS_2_2)
|
@@ -34,7 +34,7 @@ class Spawn
|
|
34
34
|
# Set the options to use every time spawn is called unless specified
|
35
35
|
# otherwise. For example, in your environment, do something like
|
36
36
|
# this:
|
37
|
-
#
|
37
|
+
# Spawnling::default_options = {:nice => 5}
|
38
38
|
# to default to using the :nice option with a value of 5 on every call.
|
39
39
|
# Valid options are:
|
40
40
|
# :method => (:thread | :fork | :yield)
|
@@ -84,12 +84,12 @@ class Spawn
|
|
84
84
|
@@punks = []
|
85
85
|
end
|
86
86
|
# register to kill marked children when parent exits
|
87
|
-
at_exit {
|
87
|
+
at_exit { Spawnling.kill_punks }
|
88
88
|
|
89
89
|
# Spawns a long-running section of code and returns the ID of the spawned process.
|
90
90
|
# By default the process will be a forked process. To use threading, pass
|
91
91
|
# :method => :thread or override the default behavior in the environment by setting
|
92
|
-
# '
|
92
|
+
# 'Spawnling::method :thread'.
|
93
93
|
def initialize(opts = {})
|
94
94
|
raise "Must give block of code to be spawned" unless block_given?
|
95
95
|
options = @@default_options.merge(symbolize_options(opts))
|
@@ -149,7 +149,7 @@ class Spawn
|
|
149
149
|
Process.setpriority(Process::PRIO_PROCESS, 0, options[:nice]) if options[:nice]
|
150
150
|
|
151
151
|
# disconnect from the listening socket, et al
|
152
|
-
|
152
|
+
Spawnling.close_resources
|
153
153
|
if defined?(Rails)
|
154
154
|
# get a new database connection so the parent can keep the original one
|
155
155
|
ActiveRecord::Base.spawn_reconnect
|
@@ -175,7 +175,7 @@ class Spawn
|
|
175
175
|
# ensure log is flushed since we are using exit!
|
176
176
|
@@logger.flush if @@logger && @@logger.respond_to?(:flush)
|
177
177
|
# this child might also have children to kill if it called spawn
|
178
|
-
|
178
|
+
Spawnling.kill_punks
|
179
179
|
# this form of exit doesn't call at_exit handlers
|
180
180
|
exit!(0)
|
181
181
|
end
|
@@ -194,7 +194,7 @@ class Spawn
|
|
194
194
|
@@logger.debug "spawn> death row = #{@@punks.inspect}" if @@logger
|
195
195
|
end
|
196
196
|
|
197
|
-
# return
|
197
|
+
# return Spawnling::Id.new(:fork, child)
|
198
198
|
return child
|
199
199
|
end
|
200
200
|
|
@@ -217,7 +217,8 @@ class Spawn
|
|
217
217
|
end
|
218
218
|
end
|
219
219
|
end
|
220
|
-
|
220
|
+
# backwards compatibility unless someone is using the "other" spawn gem
|
221
|
+
Spawn = Spawnling unless defined? Spawn
|
221
222
|
|
222
223
|
# patches depends on Spawn so require it after the class
|
223
224
|
require 'patches'
|
File without changes
|
metadata
CHANGED
@@ -1,69 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: spawnling
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.1.1
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Tom Anderson
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
date: 2010-08-08 00:00:00 Z
|
12
|
+
date: 2010-08-08 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
|
+
description: ! 'This plugin provides a ''Spawn'' class to easily fork OR
|
14
15
|
|
15
|
-
description: |-
|
16
|
-
This plugin provides a 'Spawn' class to easily fork OR
|
17
16
|
thread long-running sections of code so that your application can return
|
17
|
+
|
18
18
|
results to your users more quickly. This plugin works by creating new database
|
19
|
+
|
19
20
|
connections in ActiveRecord::Base for the spawned block.
|
20
|
-
|
21
|
+
|
22
|
+
|
21
23
|
The plugin also patches ActiveRecord::Base to handle some known bugs when using
|
22
|
-
|
23
|
-
|
24
|
+
|
25
|
+
threads (see lib/patches.rb).'
|
26
|
+
email:
|
24
27
|
- tom@squeat.com
|
25
28
|
executables: []
|
26
|
-
|
27
29
|
extensions: []
|
28
|
-
|
29
30
|
extra_rdoc_files: []
|
30
|
-
|
31
|
-
files:
|
31
|
+
files:
|
32
32
|
- lib/patches.rb
|
33
|
-
- lib/
|
34
|
-
- lib/
|
33
|
+
- lib/spawnling/cucumber.rb
|
34
|
+
- lib/spawnling.rb
|
35
35
|
- spec/spawn/spawn_spec.rb
|
36
36
|
- spec/spec_helper.rb
|
37
37
|
- CHANGELOG
|
38
38
|
- LICENSE
|
39
39
|
- README.md
|
40
40
|
- init.rb
|
41
|
-
homepage: http://github.com/tra/
|
41
|
+
homepage: http://github.com/tra/spawnling
|
42
42
|
licenses: []
|
43
|
-
|
44
|
-
metadata: {}
|
45
|
-
|
46
43
|
post_install_message:
|
47
44
|
rdoc_options: []
|
48
|
-
|
49
|
-
require_paths:
|
45
|
+
require_paths:
|
50
46
|
- lib
|
51
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
60
58
|
version: 1.3.6
|
61
59
|
requirements: []
|
62
|
-
|
63
60
|
rubyforge_project:
|
64
|
-
rubygems_version:
|
61
|
+
rubygems_version: 1.8.10
|
65
62
|
signing_key:
|
66
|
-
specification_version:
|
63
|
+
specification_version: 3
|
67
64
|
summary: Easily fork OR thread long-running sections of code in Ruby
|
68
65
|
test_files: []
|
69
|
-
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
data.tar.gz: 22c752d3c7f7e6f38838941833c5b3e05cd376e1
|
4
|
-
metadata.gz: 3ed0947f67a6a6937970268bcb2988dc56184dda
|
5
|
-
SHA512:
|
6
|
-
data.tar.gz: 858a4f1a283da28138a84b801f2943901a86bf49250804bd46477f01b5e667927bab24de0350a5f8887f210af57ae233b3e2cb45647404ff0677bb877eb3ca8c
|
7
|
-
metadata.gz: 949044c486e08b519984b6734c009568143d7d64325838f8df47f6cee75d0e8903a831f3552cf4373d25ca8a749381067fae25c327357609c917e11182f7e3a0
|