1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

threads can wait on responses to be committed

This commit is contained in:
Aaron Patterson 2012-07-27 15:54:11 -07:00
parent f4d818d51e
commit acb6848468
3 changed files with 34 additions and 1 deletions

View file

@ -226,6 +226,7 @@ module ActionController
@block = nil @block = nil
@length = 0 @length = 0
@body = [] @body = []
@committed = false
@charset = @content_type = nil @charset = @content_type = nil
@request = @template = nil @request = @template = nil
end end

View file

@ -2,6 +2,7 @@ require 'digest/md5'
require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/class/attribute_accessors'
require 'monitor'
module ActionDispatch # :nodoc: module ActionDispatch # :nodoc:
# Represents an HTTP response generated by a controller action. Use it to # Represents an HTTP response generated by a controller action. Use it to
@ -62,12 +63,17 @@ module ActionDispatch # :nodoc:
include Rack::Response::Helpers include Rack::Response::Helpers
include ActionDispatch::Http::Cache::Response include ActionDispatch::Http::Cache::Response
include MonitorMixin
def initialize(status = 200, header = {}, body = []) def initialize(status = 200, header = {}, body = [])
super()
self.body, self.header, self.status = body, header, status self.body, self.header, self.status = body, header, status
@sending_file = false @sending_file = false
@blank = false @blank = false
@cv = new_cond
@committed = false
if content_type = self[CONTENT_TYPE] if content_type = self[CONTENT_TYPE]
type, charset = content_type.split(/;\s*charset=/) type, charset = content_type.split(/;\s*charset=/)
@ -80,6 +86,23 @@ module ActionDispatch # :nodoc:
yield self if block_given? yield self if block_given?
end end
def await_commit
synchronize do
@cv.wait_until { @committed }
end
end
def commit!
synchronize do
@committed = true
@cv.broadcast
end
end
def committed?
synchronize { @committed }
end
def status=(status) def status=(status)
@status = Rack::Utils.status_code(status) @status = Rack::Utils.status_code(status)
end end

View file

@ -5,6 +5,15 @@ class ResponseTest < ActiveSupport::TestCase
@response = ActionDispatch::Response.new @response = ActionDispatch::Response.new
end end
def test_can_wait_until_commit
t = Thread.new {
assert @response.await_commit
}
@response.commit!
assert @response.committed?
t.join
end
def test_response_body_encoding def test_response_body_encoding
body = ["hello".encode('utf-8')] body = ["hello".encode('utf-8')]
response = ActionDispatch::Response.new 200, {}, body response = ActionDispatch::Response.new 200, {}, body