Skip to content

Commit

Permalink
Define deferred?(env) in your Rack application to set if a request is…
Browse files Browse the repository at this point in the history
… handled in a thread (return true) or not (return false).
  • Loading branch information
macournoyer committed Apr 9, 2008
1 parent 77b0f72 commit b02c717
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
== 0.8.1 Rebel Porpoise release
* Define deferred?(env) in your Rack application to set if a request is handled in a
thread (return true) or not (return false).

== 0.8.0 Dodgy Dentist release
* Fix server crash when header too large.
* Add --require (-r) option to require a library, before executing your script.
Expand Down
16 changes: 11 additions & 5 deletions lib/thin/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@ class Connection < EventMachine::Connection

# Calling the application in a threaded allowing
# concurrent processing of requests.
attr_accessor :threaded
attr_writer :threaded

# Get the connection ready to process a request.
def post_init
@request = Request.new
@response = Response.new

@request.threaded = threaded
end

# Called when data is received from the client.
Expand All @@ -44,7 +42,7 @@ def receive_data(data)
# Called when all data was received and the request
# is ready to be processed.
def process
if @threaded
if threaded?
EventMachine.defer(method(:pre_process), method(:post_process))
else
post_process(pre_process)
Expand All @@ -54,6 +52,7 @@ def process
def pre_process
# Add client info to the request env
@request.remote_address = remote_address
@request.threaded = threaded?

# Process the request calling the Rack adapter
@app.call(@request.env)
Expand Down Expand Up @@ -121,7 +120,14 @@ def can_persist?
# and ready to be reused for another request.
def persistent?
@can_persist && @response.persistent?
end
end

# +true+ if <tt>app.call</tt> will be called inside a thread.
# You can set all requests as threaded setting <tt>Connection#threaded=true</tt>
# or on a per-request case returning +true+ in <tt>app.deferred?</tt>.
def threaded?
@threaded || (@app.respond_to?(:deferred?) && @app.deferred?(@request.env))
end

# IP Address of the remote client.
def remote_address
Expand Down
4 changes: 2 additions & 2 deletions lib/thin/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ class PlatformNotSupported < RuntimeError; end
module VERSION #:nodoc:
MAJOR = 0
MINOR = 8
TINY = 0
TINY = 1

STRING = [MAJOR, MINOR, TINY].join('.')

CODENAME = 'Dodgy Dentist'
CODENAME = 'Rebel Porpoise'

RACK = [0, 3].freeze # Latest Rack version that was tested
end
Expand Down
16 changes: 15 additions & 1 deletion spec/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,22 @@

it "should set request env as rack.multithread" do
@connection.threaded = true
@connection.post_init
@connection.pre_process

@connection.request.env["rack.multithread"].should == true
end

it "should set as threaded when app.deferred? is true" do
@connection.app.should_receive(:deferred?).and_return(true)
@connection.should be_threaded
end

it "should not set as threaded when app.deferred? is false" do
@connection.app.should_receive(:deferred?).and_return(false)
@connection.should_not be_threaded
end

it "should not set as threaded when app do not respond to deferred?" do
@connection.should_not be_threaded
end
end

0 comments on commit b02c717

Please sign in to comment.