Skip to content

Commit

Permalink
Add rb_thread_schedule() and threaded_processing option
Browse files Browse the repository at this point in the history
This change should allow Ebb to work like mongrel with threaded processing or like Thin with sequential processing. There are trade off for each, thus i've made it a command line option '-S'

By default Ebb will use threaded processing because it seems that is working best. But only time will tell if that is the correction thing to do.
  • Loading branch information
Ryan Dahl committed Mar 11, 2008
1 parent 274c811 commit 023a85c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 17 deletions.
17 changes: 11 additions & 6 deletions benchmark/server_test.rb
Expand Up @@ -92,10 +92,10 @@ def start
case name
when 'emongrel'
@pid = fork { start_emongrel }
when /^ebb(\d*)$/
workers = $1.to_i
workers = 1 if workers <= 0
@pid = fork { start_ebb(workers) }
when 'ebb_threaded'
@pid = fork { start_ebb_threaded }
when 'ebb_sequential'
@pid = fork { start_ebb_sequential }
when 'mongrel'
@pid = fork { start_mongrel }
when 'thin'
Expand All @@ -116,9 +116,14 @@ def start_emongrel
Rack::Handler::Mongrel.run(app, :Host => '0.0.0.0', :Port => @port.to_i)
end

def start_ebb(workers = 1)
def start_ebb_threaded
require File.dirname(__FILE__) + '/../ruby_lib/ebb'
server = Ebb::start_server(app, :port => @port, :workers => workers)
server = Ebb::start_server(app, :port => @port, :threaded_processing => true)
end

def start_ebb_sequential
require File.dirname(__FILE__) + '/../ruby_lib/ebb'
server = Ebb::start_server(app, :port => @port, :threaded_processing => false)
end

def start_mongrel
Expand Down
20 changes: 15 additions & 5 deletions ruby_lib/ebb.rb
Expand Up @@ -9,18 +9,28 @@ module Ebb

def self.start_server(app, options={})
port = (options[:port] || 4001).to_i
FFI::server_listen_on_port(port)
if options.has_key?(:threaded_processing)
threaded_processing = options[:threaded_processing] ? true : false
else
threaded_processing = true
end

puts "Ebb listening at http://0.0.0.0:#{port}/"
Client::BASE_ENV['rack.multithread'] = threaded_processing

FFI::server_listen_on_port(port)

puts "Ebb listening at http://0.0.0.0:#{port}/ (#{threaded_processing ? 'threaded' : 'sequential'} processing)"
trap('INT') { @running = false }
@running = true

while @running
FFI::server_process_connections()
while client = FFI::waiting_clients.shift
#process_client(app, client)
Thread.new(client) { |c| c.process(app) }
if threaded_processing
Thread.new(client) { |c| c.process(app) }
else
client.process(app)
end
end
end

Expand Down Expand Up @@ -157,4 +167,4 @@ def each
504 => 'Gateway Time-out',
505 => 'HTTP Version not supported'
}.freeze
end
end
9 changes: 8 additions & 1 deletion ruby_lib/ebb/runner.rb
Expand Up @@ -23,7 +23,8 @@ class Runner
DEFAULT_OPTIONS = {
:port => 4001,
:timeout => 60,
:workers => 1
:workers => 1,
:threaded_processing => true
}

# Kill the process which PID is stored in +pid_file+.
Expand Down Expand Up @@ -119,6 +120,12 @@ def get_options_from_command_line
parser.on("-P", "--pid-file FILE", "File to store PID") { |f| options[:pid_file]=f }
parser.on("-t", "--timeout SECONDS", "(default: #{options[:timeout]})") { |s| options[:timeout]=s }
#parser.on("-w", "--workers WORKERS", "Number of worker threads (default: #{options[:workers]})") { |w| options[:workers]=w }
parser.on("-w", "-- WORKERS", "Number of worker threads (default: #{options[:workers]})") { |w| options[:workers]=w }

parser.on("-S", "--sequential", "do not use threaded processing") do
options[:threaded_processing] = false
end

parser.separator ""
parser.on_tail("-h", "--help", "Show this message") do
puts parser
Expand Down
13 changes: 8 additions & 5 deletions src/ebb_ruby.c
Expand Up @@ -58,14 +58,17 @@ VALUE server_process_connections(VALUE _)
{
ev_timer timeout;
ev_timer_init (&timeout, oneshot_timeout, 0.01, 0.);
ev_timer_start (loop, &timeout);

ev_timer_start (loop, &timeout);
ev_loop(loop, EVLOOP_ONESHOT);
/* XXX: Need way to know when the loop is finished...
* should return true or false */

ev_timer_stop(loop, &timeout);

/* Call rb_thread_schedule() proportional to the number of rb threads running */
/* SO HACKY! Anyone have a better way to do this? */
int i;
for(i = 0; i < EBB_MAX_CLIENTS; i++)
if(server->clients[i].in_use)
rb_thread_schedule();

if(server->open)
return Qtrue;
else
Expand Down

0 comments on commit 023a85c

Please sign in to comment.