From fa622de470d475f0afc94cb619cc69e7e127830c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 22 Dec 2009 01:22:32 -0800 Subject: common Rainbows.sleep(nr) method We'll export this across the board to all Rack applications to sleep with. This provides the optimum method of sleeping regardless of the concurrency model you choose. This method is still highly not recommended for pure event-driven models like Rev or EventMachine (but the threaded/fiber/actor-based variants are fine). --- Documentation/comparison.haml | 6 +++--- lib/rainbows.rb | 18 ++++++++++++++++++ lib/rainbows/fiber/base.rb | 3 ++- lib/rainbows/fiber/rev.rb | 6 ------ t/simple-http_Revactor.ru | 1 - t/simple-http_ThreadPool.ru | 1 - t/simple-http_ThreadSpawn.ru | 1 - t/sleep.ru | 11 +---------- t/t9000.ru | 11 +---------- t/worker-follows-master-to-death.ru | 7 +------ 10 files changed, 26 insertions(+), 39 deletions(-) diff --git a/Documentation/comparison.haml b/Documentation/comparison.haml index cccd311..49531f9 100644 --- a/Documentation/comparison.haml +++ b/Documentation/comparison.haml @@ -289,14 +289,14 @@ %td.devfd Yes %td.app_pool Yes %td.lock No! - %td.async Rainbows::Fiber{::IO,.sleep} + %td.async Rainbows::Fiber::IO, Rainbows.sleep %td.ws Sunshowers %tr.comp_row %td.mod FiberPool %td.devfd Yes %td.app_pool Yes %td.lock No! - %td.async Rainbows::Fiber{::IO,.sleep} + %td.async Rainbows::Fiber::IO, Rainbows.sleep %td.ws Sunshowers %tr.comp_row %td.mod ActorSpawn @@ -324,7 +324,7 @@ %td.devfd Yes %td.app_pool Yes %td.lock No! - %td.async Rainbows::Fiber::IO, Rainbows::Fiber::Rev.sleep + %td.async Rainbows::Fiber::IO, Rainbows.sleep %ul %li diff --git a/lib/rainbows.rb b/lib/rainbows.rb index 0b6402a..d3a3e7d 100644 --- a/lib/rainbows.rb +++ b/lib/rainbows.rb @@ -34,6 +34,24 @@ module Rainbows class << self + # Sleeps the current application dispatch. This will pick the + # optimal method to sleep depending on the concurrency model chosen + # (which may still suck and block the entire process). Using this + # with the basic :Rev or :EventMachine models is not recommended. + # This should be used within your Rack application. + def sleep(nr) + case G.server.use + when :FiberPool, :FiberSpawn + Rainbows::Fiber.sleep(nr) + when :RevFiberSpawn + Rainbows::Fiber::Rev::Sleeper.new(nr) + when :Revactor + Actor.sleep(nr) + else + Kernel.sleep(nr) + end + end + # runs the Rainbows! HttpServer with +app+ and +options+ and does # not return until the server has exited. def run(app, options = {}) diff --git a/lib/rainbows/fiber/base.rb b/lib/rainbows/fiber/base.rb index 1617c54..090a9e4 100644 --- a/lib/rainbows/fiber/base.rb +++ b/lib/rainbows/fiber/base.rb @@ -16,7 +16,8 @@ module Rainbows # puts the current Fiber into uninterruptible sleep for at least # +seconds+. Unlike Kernel#sleep, this it is not possible to sleep # indefinitely to be woken up (nobody wants that in a web server, - # right?). + # right?). Calling this directly is deprecated, use + # Rainbows.sleep(seconds) instead. def self.sleep(seconds) ZZ[::Fiber.current] = Time.now + seconds ::Fiber.yield diff --git a/lib/rainbows/fiber/rev.rb b/lib/rainbows/fiber/rev.rb index 36a46d4..bd9638f 100644 --- a/lib/rainbows/fiber/rev.rb +++ b/lib/rainbows/fiber/rev.rb @@ -108,12 +108,6 @@ module Rainbows::Fiber client.close end end - - # TODO: env["rainbows.sleep"] - def self.sleep(seconds) - Sleeper.new(seconds) - end - end class IO # see rainbows/fiber/io for original definition diff --git a/t/simple-http_Revactor.ru b/t/simple-http_Revactor.ru index 9b9c56a..aa37aea 100644 --- a/t/simple-http_Revactor.ru +++ b/t/simple-http_Revactor.ru @@ -1,7 +1,6 @@ use Rack::ContentLength use Rack::ContentType run lambda { |env| - Actor.sleep 1 if env['rack.multithread'] == false && env['rainbows.model'] == :Revactor [ 200, {}, [ Thread.current.inspect << "\n" ] ] else diff --git a/t/simple-http_ThreadPool.ru b/t/simple-http_ThreadPool.ru index 4bb7348..cd5df82 100644 --- a/t/simple-http_ThreadPool.ru +++ b/t/simple-http_ThreadPool.ru @@ -1,7 +1,6 @@ use Rack::ContentLength use Rack::ContentType run lambda { |env| - sleep 1 if env['rack.multithread'] && env['rainbows.model'] == :ThreadPool [ 200, {}, [ Thread.current.inspect << "\n" ] ] else diff --git a/t/simple-http_ThreadSpawn.ru b/t/simple-http_ThreadSpawn.ru index aa1accb..ea5dee2 100644 --- a/t/simple-http_ThreadSpawn.ru +++ b/t/simple-http_ThreadSpawn.ru @@ -1,7 +1,6 @@ use Rack::ContentLength use Rack::ContentType run lambda { |env| - sleep 1 if env['rack.multithread'] && env['rainbows.model'] == :ThreadSpawn [ 200, {}, [ Thread.current.inspect << "\n" ] ] else diff --git a/t/sleep.ru b/t/sleep.ru index d0fd832..b57efc3 100644 --- a/t/sleep.ru +++ b/t/sleep.ru @@ -7,16 +7,7 @@ run lambda { |env| nr = 1 env["PATH_INFO"] =~ %r{/([\d\.]+)\z} and nr = $1.to_f - (case env['rainbows.model'] - when :FiberPool, :FiberSpawn - Rainbows::Fiber - when :Revactor - Actor - when :RevFiberSpawn - Rainbows::Fiber::Rev - else - Kernel - end).sleep(nr) + Rainbows.sleep(nr) [ 200, {'Content-Type' => 'text/plain'}, [ "Hello\n" ] ] } diff --git a/t/t9000.ru b/t/t9000.ru index abf36b2..66643b6 100644 --- a/t/t9000.ru +++ b/t/t9000.ru @@ -3,16 +3,7 @@ use Rack::ContentType use Rainbows::AppPool, :size => ENV['APP_POOL_SIZE'].to_i class Sleeper def call(env) - (case env['rainbows.model'] - when :FiberPool, :FiberSpawn - Rainbows::Fiber - when :Revactor - Actor - when :RevFiberSpawn - Rainbows::Fiber::Rev - else - Kernel - end).sleep(1) + Rainbows.sleep(1) [ 200, {}, [ "#{object_id}\n" ] ] end end diff --git a/t/worker-follows-master-to-death.ru b/t/worker-follows-master-to-death.ru index ed2a519..b372afd 100644 --- a/t/worker-follows-master-to-death.ru +++ b/t/worker-follows-master-to-death.ru @@ -6,12 +6,7 @@ run lambda { |env| case env["PATH_INFO"] when %r{/sleep/(\d+)} - (case env['rainbows.model'] - when :Revactor - Actor - else - Kernel - end).sleep($1.to_i) + Rainbows.sleep($1.to_i) end [ 200, headers, [ "#$$\n" ] ] } -- cgit v1.2.3-24-ge0c7