mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Less ceremony
This commit is contained in:
parent
2f998fc81f
commit
4a7b11d5d8
5 changed files with 59 additions and 87 deletions
25
actionpack/lib/action_view/body_parts/concurrent_block.rb
Normal file
25
actionpack/lib/action_view/body_parts/concurrent_block.rb
Normal 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
|
|
@ -1,10 +0,0 @@
|
|||
module ActionView
|
||||
module BodyParts
|
||||
class Future
|
||||
def to_s
|
||||
finish
|
||||
body
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -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
|
|
@ -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
|
|
@ -1,37 +1,44 @@
|
|||
require 'abstract_unit'
|
||||
require 'action_view/body_parts/queued'
|
||||
require 'action_view/body_parts/threaded'
|
||||
require 'action_view/body_parts/concurrent_block'
|
||||
|
||||
|
||||
class QueuedPartTest < ActionController::TestCase
|
||||
class EdgeSideInclude < ActionView::BodyParts::Queued
|
||||
QUEUE_REDEMPTION_URL = 'http://queue/jobs/%s'
|
||||
class BodyPartTest < ActionController::TestCase
|
||||
module EdgeSideInclude
|
||||
QUEUE_REDEMPTION_URL = 'http://render.farm/renderings/%s'
|
||||
ESI_INCLUDE_TAG = '<esi:include src="%s" />'
|
||||
|
||||
def self.redemption_tag(receipt)
|
||||
ESI_INCLUDE_TAG % QUEUE_REDEMPTION_URL % receipt
|
||||
end
|
||||
|
||||
protected
|
||||
def enqueue(job)
|
||||
job.reverse
|
||||
class BodyPart
|
||||
def initialize(rendering)
|
||||
@receipt = enqueue(rendering)
|
||||
end
|
||||
|
||||
def redeem(receipt)
|
||||
self.class.redemption_tag(receipt)
|
||||
def to_s
|
||||
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
|
||||
|
||||
class TestController < ActionController::Base
|
||||
RENDERINGS = [Object.new, Object.new, Object.new]
|
||||
|
||||
def index
|
||||
edge_side_include 'foo'
|
||||
edge_side_include 'bar'
|
||||
edge_side_include 'baz'
|
||||
RENDERINGS.each do |rendering|
|
||||
edge_side_include rendering
|
||||
end
|
||||
@performed_render = true
|
||||
end
|
||||
|
||||
def edge_side_include(job)
|
||||
response.template.punctuate_body! EdgeSideInclude.new(job)
|
||||
def edge_side_include(rendering)
|
||||
response.template.punctuate_body! EdgeSideInclude::BodyPart.new(rendering)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -39,20 +46,20 @@ class QueuedPartTest < ActionController::TestCase
|
|||
|
||||
def test_queued_parts
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class ThreadedPartTest < ActionController::TestCase
|
||||
class ConcurrentBlockPartTest < ActionController::TestCase
|
||||
class TestController < ActionController::Base
|
||||
def index
|
||||
append_thread_id = lambda do |parts|
|
||||
parts << Thread.current.object_id
|
||||
parts << '::'
|
||||
parts << Time.now.to_i
|
||||
sleep 1
|
||||
sleep 0.1
|
||||
end
|
||||
|
||||
future_render &append_thread_id
|
||||
|
@ -62,16 +69,16 @@ class ThreadedPartTest < ActionController::TestCase
|
|||
response.body_parts << '-'
|
||||
|
||||
future_render do |parts|
|
||||
parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id)
|
||||
parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id)
|
||||
parts << '-'
|
||||
parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id)
|
||||
parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id)
|
||||
end
|
||||
|
||||
@performed_render = true
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
|
@ -84,16 +91,16 @@ class ThreadedPartTest < ActionController::TestCase
|
|||
thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i }
|
||||
assert_equal thread_ids.size, thread_ids.uniq.size
|
||||
end
|
||||
assert (elapsed - 1000).abs < 100, elapsed
|
||||
assert (elapsed - 100).abs < 10, elapsed
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class OpenUriPartTest < ActionController::TestCase
|
||||
class OpenUriPart < ActionView::BodyParts::Threaded
|
||||
class OpenUriPart < ActionView::BodyParts::ConcurrentBlock
|
||||
def initialize(url)
|
||||
url = URI::Generic === url ? url : URI.parse(url)
|
||||
super(true) { |parts| parts << url.read }
|
||||
super() { |body| body << url.read }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -107,7 +114,7 @@ class OpenUriPartTest < ActionController::TestCase
|
|||
|
||||
def render_url(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)
|
||||
end
|
||||
end
|
||||
|
@ -120,6 +127,6 @@ class OpenUriPartTest < ActionController::TestCase
|
|||
elapsed = Benchmark.ms do
|
||||
assert_equal '/foo/bar/baz', @response.body
|
||||
end
|
||||
assert (elapsed - 1000).abs < 100, elapsed
|
||||
assert (elapsed - 100).abs < 10, elapsed
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue