提交 acb68484 编写于 作者: A Aaron Patterson

threads can wait on responses to be committed

上级 f4d818d5
...@@ -226,6 +226,7 @@ def recycle! ...@@ -226,6 +226,7 @@ def recycle!
@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 @@ ...@@ -2,6 +2,7 @@
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 @@ class Response ...@@ -62,12 +63,17 @@ class Response
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 @@ def initialize(status = 200, header = {}, body = []) ...@@ -80,6 +86,23 @@ def initialize(status = 200, header = {}, body = [])
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 @@ def setup ...@@ -5,6 +5,15 @@ def setup
@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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册