spawnling 2.1 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|