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:
parent
f4d818d51e
commit
acb6848468
3 changed files with 34 additions and 1 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue