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

Less ceremony

This commit is contained in:
Jeremy Kemper 2009-03-13 18:49:53 -07:00
parent 2f998fc81f
commit 4a7b11d5d8
5 changed files with 59 additions and 87 deletions

View file

@ -0,0 +1,25 @@
module ActionView
module BodyParts
class ConcurrentBlock
def initialize(&block)
@block = block
@body = []
start
end
def to_s
finish
@body.join
end
protected
def start
@worker = Thread.new { @block.call(@body) }
end
def finish
@worker.join if @worker && @worker.alive?
end
end
end
end

View file

@ -1,10 +0,0 @@
module ActionView
module BodyParts
class Future
def to_s
finish
body
end
end
end
end

View file

@ -1,18 +0,0 @@
require 'action_view/body_parts/future'
module ActionView
module BodyParts
class Queued < Future
attr_reader :body
def initialize(job)
@receipt = enqueue(job)
end
protected
def finish
@body = redeem(@receipt)
end
end
end
end

View file

@ -1,32 +0,0 @@
require 'action_view/body_parts/future'
module ActionView
module BodyParts
class Threaded < Future
def initialize(concurrent = false, &block)
@block = block
@parts = []
concurrent ? start : work
end
protected
def work
@block.call(@parts)
end
def body
str = ''
@parts.each { |part| str << part.to_s }
str
end
def start
@worker = Thread.new { work }
end
def finish
@worker.join if @worker && @worker.alive?
end
end
end
end

View file

@ -1,37 +1,44 @@
require 'abstract_unit' require 'abstract_unit'
require 'action_view/body_parts/queued' require 'action_view/body_parts/concurrent_block'
require 'action_view/body_parts/threaded'
class BodyPartTest < ActionController::TestCase
class QueuedPartTest < ActionController::TestCase module EdgeSideInclude
class EdgeSideInclude < ActionView::BodyParts::Queued QUEUE_REDEMPTION_URL = 'http://render.farm/renderings/%s'
QUEUE_REDEMPTION_URL = 'http://queue/jobs/%s'
ESI_INCLUDE_TAG = '<esi:include src="%s" />' ESI_INCLUDE_TAG = '<esi:include src="%s" />'
def self.redemption_tag(receipt) def self.redemption_tag(receipt)
ESI_INCLUDE_TAG % QUEUE_REDEMPTION_URL % receipt ESI_INCLUDE_TAG % QUEUE_REDEMPTION_URL % receipt
end end
protected class BodyPart
def enqueue(job) def initialize(rendering)
job.reverse @receipt = enqueue(rendering)
end end
def redeem(receipt) def to_s
self.class.redemption_tag(receipt) EdgeSideInclude.redemption_tag(@receipt)
end
protected
# Pretend we sent this rendering off for processing.
def enqueue(rendering)
rendering.object_id.to_s
end
end end
end end
class TestController < ActionController::Base class TestController < ActionController::Base
RENDERINGS = [Object.new, Object.new, Object.new]
def index def index
edge_side_include 'foo' RENDERINGS.each do |rendering|
edge_side_include 'bar' edge_side_include rendering
edge_side_include 'baz' end
@performed_render = true @performed_render = true
end end
def edge_side_include(job) def edge_side_include(rendering)
response.template.punctuate_body! EdgeSideInclude.new(job) response.template.punctuate_body! EdgeSideInclude::BodyPart.new(rendering)
end end
end end
@ -39,20 +46,20 @@ class QueuedPartTest < ActionController::TestCase
def test_queued_parts def test_queued_parts
get :index get :index
expected = %w(oof rab zab).map { |receipt| EdgeSideInclude.redemption_tag(receipt) }.join expected = TestController::RENDERINGS.map { |rendering| EdgeSideInclude.redemption_tag(rendering.object_id) }.join
assert_equal expected, @response.body assert_equal expected, @response.body
end end
end end
class ThreadedPartTest < ActionController::TestCase class ConcurrentBlockPartTest < ActionController::TestCase
class TestController < ActionController::Base class TestController < ActionController::Base
def index def index
append_thread_id = lambda do |parts| append_thread_id = lambda do |parts|
parts << Thread.current.object_id parts << Thread.current.object_id
parts << '::' parts << '::'
parts << Time.now.to_i parts << Time.now.to_i
sleep 1 sleep 0.1
end end
future_render &append_thread_id future_render &append_thread_id
@ -62,16 +69,16 @@ class ThreadedPartTest < ActionController::TestCase
response.body_parts << '-' response.body_parts << '-'
future_render do |parts| future_render do |parts|
parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id) parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id)
parts << '-' parts << '-'
parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id) parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id)
end end
@performed_render = true @performed_render = true
end end
def future_render(&block) def future_render(&block)
response.template.punctuate_body! ActionView::BodyParts::Threaded.new(true, &block) response.template.punctuate_body! ActionView::BodyParts::ConcurrentBlock.new(&block)
end end
end end
@ -84,16 +91,16 @@ class ThreadedPartTest < ActionController::TestCase
thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i } thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i }
assert_equal thread_ids.size, thread_ids.uniq.size assert_equal thread_ids.size, thread_ids.uniq.size
end end
assert (elapsed - 1000).abs < 100, elapsed assert (elapsed - 100).abs < 10, elapsed
end end
end end
class OpenUriPartTest < ActionController::TestCase class OpenUriPartTest < ActionController::TestCase
class OpenUriPart < ActionView::BodyParts::Threaded class OpenUriPart < ActionView::BodyParts::ConcurrentBlock
def initialize(url) def initialize(url)
url = URI::Generic === url ? url : URI.parse(url) url = URI::Generic === url ? url : URI.parse(url)
super(true) { |parts| parts << url.read } super() { |body| body << url.read }
end end
end end
@ -107,7 +114,7 @@ class OpenUriPartTest < ActionController::TestCase
def render_url(url) def render_url(url)
url = URI.parse(url) url = URI.parse(url)
def url.read; sleep 1; path end def url.read; sleep 0.1; path end
response.template.punctuate_body! OpenUriPart.new(url) response.template.punctuate_body! OpenUriPart.new(url)
end end
end end
@ -120,6 +127,6 @@ class OpenUriPartTest < ActionController::TestCase
elapsed = Benchmark.ms do elapsed = Benchmark.ms do
assert_equal '/foo/bar/baz', @response.body assert_equal '/foo/bar/baz', @response.body
end end
assert (elapsed - 1000).abs < 100, elapsed assert (elapsed - 100).abs < 10, elapsed
end end
end end