about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-11-29 16:19:02 -0800
committerEric Wong <normalperson@yhbt.net>2009-11-29 17:50:54 -0800
commit16c0391066b38e5f3ea834b59632645890519574 (patch)
tree0f4475073323b0bc5c032fe21ae1052e57def75b /lib
parentf050fcb9e5da4adf3b5b4f65c0590360113e78fd (diff)
downloadrainbows-16c0391066b38e5f3ea834b59632645890519574.tar.gz
Diffstat (limited to 'lib')
-rw-r--r--lib/rainbows.rb1
-rw-r--r--lib/rainbows/app_pool.rb2
-rw-r--r--lib/rainbows/fiber.rb6
-rw-r--r--lib/rainbows/http_server.rb2
-rw-r--r--lib/rainbows/never_block.rb69
5 files changed, 77 insertions, 3 deletions
diff --git a/lib/rainbows.rb b/lib/rainbows.rb
index f2f7af5..c8f77c0 100644
--- a/lib/rainbows.rb
+++ b/lib/rainbows.rb
@@ -82,6 +82,7 @@ module Rainbows
     :FiberSpawn => 50,
     :FiberPool => 50,
     :ActorSpawn => 50,
+    :NeverBlock => 50,
   }.each do |model, _|
     u = model.to_s.gsub(/([a-z0-9])([A-Z0-9])/) { "#{$1}_#{$2.downcase!}" }
     autoload model, "rainbows/#{u.downcase!}"
diff --git a/lib/rainbows/app_pool.rb b/lib/rainbows/app_pool.rb
index 5c85e0a..036fe9c 100644
--- a/lib/rainbows/app_pool.rb
+++ b/lib/rainbows/app_pool.rb
@@ -91,7 +91,7 @@ module Rainbows
       # concurrency models
       self.re ||= begin
         case env["rainbows.model"]
-        when :FiberSpawn, :FiberPool, :Revactor
+        when :FiberSpawn, :FiberPool, :Revactor, :NeverBlock
           self.pool = Rainbows::Fiber::Queue.new(pool)
         end
         true
diff --git a/lib/rainbows/fiber.rb b/lib/rainbows/fiber.rb
index c30bd7a..ec0cee3 100644
--- a/lib/rainbows/fiber.rb
+++ b/lib/rainbows/fiber.rb
@@ -1,5 +1,9 @@
 # -*- encoding: binary -*-
-require 'fiber'
+begin
+  require 'fiber'
+rescue LoadError
+  defined?(NeverBlock) or raise
+end
 
 module Rainbows
 
diff --git a/lib/rainbows/http_server.rb b/lib/rainbows/http_server.rb
index b528942..8b9f220 100644
--- a/lib/rainbows/http_server.rb
+++ b/lib/rainbows/http_server.rb
@@ -63,7 +63,7 @@ module Rainbows
       Const::RACK_DEFAULTS['rainbows.model'] = @use = model.to_sym
       Const::RACK_DEFAULTS['rack.multithread'] = !!(/Thread/ =~ model.to_s)
       case @use
-      when :Rev, :EventMachine
+      when :Rev, :EventMachine, :NeverBlock
         Const::RACK_DEFAULTS['rainbows.autochunk'] = true
       end
     end
diff --git a/lib/rainbows/never_block.rb b/lib/rainbows/never_block.rb
new file mode 100644
index 0000000..0933c73
--- /dev/null
+++ b/lib/rainbows/never_block.rb
@@ -0,0 +1,69 @@
+# -*- encoding: binary -*-
+
+module Rainbows
+
+  # {NeverBlock}[www.espace.com.eg/neverblock/] library that combines
+  # the EventMachine library with Ruby Fibers.  This includes use of
+  # Thread-based Fibers under Ruby 1.8.  It currently does NOT support
+  # a streaming "rack.input" but is compatible with everything else
+  # EventMachine supports.
+  #
+  # In your Rainbows! config block, you may specify a Fiber pool size
+  # to limit your application concurrency (without using Rainbows::AppPool)
+  #
+  #   Rainbows! do
+  #     use :NeverBlock, :pool_size => 50
+  #     worker_connections 100
+  #   end
+  #
+  module NeverBlock
+
+    DEFAULTS = {
+      :pool_size => 20, # same default size used by NB
+      :backend => :EventMachine, # NeverBlock doesn't support Rev yet
+    }
+
+    # same pool size NB core itself uses
+    def self.setup
+      DEFAULTS.each { |k,v| O[k] ||= v }
+      Integer === O[:pool_size] && O[:pool_size] > 0 or
+        raise ArgumentError, "pool_size must a be an Integer > 0"
+      mod = Rainbows.const_get(O[:backend])
+      require "never_block" # require EM first since we need a higher version
+      G.server.extend(mod)
+      G.server.extend(Core)
+    end
+
+    module Client
+
+      def self.setup
+        const_set(:POOL, ::NB::Pool::FiberPool.new(O[:pool_size]))
+        Rainbows.const_get(O[:backend]).const_get(:Client).module_eval do
+          include Rainbows::NeverBlock::Client
+          alias _app_call app_call
+          undef_method :app_call
+          alias app_call nb_app_call
+        end
+      end
+
+      def nb_app_call
+        POOL.spawn do
+          begin
+            _app_call
+          rescue => e
+            handle_error(e)
+          end
+        end
+      end
+    end
+
+    module Core
+      def init_worker_process(worker)
+        super
+        Client.setup
+        logger.info "NeverBlock/#{O[:backend]} pool_size=#{O[:pool_size]}"
+      end
+    end
+
+  end
+end