ry / ebb fork watch download tarball
public this repo is viewable by everyone
Description: web server
Homepage: http://ebb.rubyforge.org
Clone URL: git://github.com/ry/ebb.git
Add rb_thread_schedule() and threaded_processing option

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.
Ryan Dahl (author)
2 months ago
commit  023a85c3083bea17375f24c751af8fd97214b8ba
tree    a6f528c056a1c6aa59c5f9a74bc8c12e5f84da5b
parent  274c811b4e810134dbfb118402190151cc752688
...
92
93
94
95
96
97
98
 
 
 
 
99
100
101
...
116
117
118
119
 
120
121
 
 
 
 
 
 
122
123
124
...
92
93
94
 
 
 
 
95
96
97
98
99
100
101
...
116
117
118
 
119
120
 
121
122
123
124
125
126
127
128
129
0
@@ -92,10 +92,10 @@ class ServerTest
0
     case name
0
     when 'emongrel'
0
       @pid = fork { start_emongrel }
0
- when /^ebb(\d*)$/
0
- workers = $1.to_i
0
- workers = 1 if workers <= 0
0
- @pid = fork { start_ebb(workers) }
0
+ when 'ebb_threaded'
0
+ @pid = fork { start_ebb_threaded }
0
+ when 'ebb_sequential'
0
+ @pid = fork { start_ebb_sequential }
0
     when 'mongrel'
0
       @pid = fork { start_mongrel }
0
     when 'thin'
0
@@ -116,9 +116,14 @@ class ServerTest
0
     Rack::Handler::Mongrel.run(app, :Host => '0.0.0.0', :Port => @port.to_i)
0
   end
0
   
0
- def start_ebb(workers = 1)
0
+ def start_ebb_threaded
0
     require File.dirname(__FILE__) + '/../ruby_lib/ebb'
0
- server = Ebb::start_server(app, :port => @port, :workers => workers)
0
+ server = Ebb::start_server(app, :port => @port, :threaded_processing => true)
0
+ end
0
+
0
+ def start_ebb_sequential
0
+ require File.dirname(__FILE__) + '/../ruby_lib/ebb'
0
+ server = Ebb::start_server(app, :port => @port, :threaded_processing => false)
0
   end
0
   
0
   def start_mongrel
...
9
10
11
12
 
 
 
 
 
13
14
 
 
 
15
 
16
17
18
19
20
21
22
23
 
 
 
 
 
24
25
26
...
157
158
159
160
161
 
...
9
10
11
 
12
13
14
15
16
17
 
18
19
20
21
22
23
24
25
26
27
28
 
 
29
30
31
32
33
34
35
36
...
167
168
169
 
170
171
0
@@ -9,18 +9,28 @@ module Ebb
0
   
0
   def self.start_server(app, options={})
0
     port = (options[:port] || 4001).to_i
0
- FFI::server_listen_on_port(port)
0
+ if options.has_key?(:threaded_processing)
0
+ threaded_processing = options[:threaded_processing] ? true : false
0
+ else
0
+ threaded_processing = true
0
+ end
0
     
0
- puts "Ebb listening at http://0.0.0.0:#{port}/"
0
+ Client::BASE_ENV['rack.multithread'] = threaded_processing
0
+
0
+ FFI::server_listen_on_port(port)
0
     
0
+ puts "Ebb listening at http://0.0.0.0:#{port}/ (#{threaded_processing ? 'threaded' : 'sequential'} processing)"
0
     trap('INT') { @running = false }
0
     @running = true
0
     
0
     while @running
0
       FFI::server_process_connections()
0
       while client = FFI::waiting_clients.shift
0
- #process_client(app, client)
0
- Thread.new(client) { |c| c.process(app) }
0
+ if threaded_processing
0
+ Thread.new(client) { |c| c.process(app) }
0
+ else
0
+ client.process(app)
0
+ end
0
       end
0
     end
0
     
0
@@ -157,4 +167,4 @@ module Ebb
0
     504 => 'Gateway Time-out',
0
     505 => 'HTTP Version not supported'
0
   }.freeze
0
-end
0
\ No newline at end of file
0
+end
...
23
24
25
26
 
 
27
28
29
...
119
120
121
 
 
 
 
 
 
122
123
124
...
23
24
25
 
26
27
28
29
30
...
120
121
122
123
124
125
126
127
128
129
130
131
0
@@ -23,7 +23,8 @@ module Ebb
0
     DEFAULT_OPTIONS = {
0
       :port => 4001,
0
       :timeout => 60,
0
- :workers => 1
0
+ :workers => 1,
0
+ :threaded_processing => true
0
     }
0
     
0
     # Kill the process which PID is stored in +pid_file+.
0
@@ -119,6 +120,12 @@ module Ebb
0
         parser.on("-P", "--pid-file FILE", "File to store PID") { |f| options[:pid_file]=f }
0
         parser.on("-t", "--timeout SECONDS", "(default: #{options[:timeout]})") { |s| options[:timeout]=s }
0
         #parser.on("-w", "--workers WORKERS", "Number of worker threads (default: #{options[:workers]})") { |w| options[:workers]=w }
0
+ parser.on("-w", "-- WORKERS", "Number of worker threads (default: #{options[:workers]})") { |w| options[:workers]=w }
0
+
0
+ parser.on("-S", "--sequential", "do not use threaded processing") do
0
+ options[:threaded_processing] = false
0
+ end
0
+
0
         parser.separator ""
0
         parser.on_tail("-h", "--help", "Show this message") do
0
           puts parser
...
58
59
60
61
62
 
63
64
65
66
67
68
 
 
 
 
 
 
 
69
70
71
...
58
59
60
 
 
61
62
 
 
 
63
64
65
66
67
68
69
70
71
72
73
74
0
@@ -58,14 +58,17 @@ VALUE server_process_connections(VALUE _)
0
 {
0
   ev_timer timeout;
0
   ev_timer_init (&timeout, oneshot_timeout, 0.01, 0.);
0
- ev_timer_start (loop, &timeout);
0
-
0
+ ev_timer_start (loop, &timeout);
0
   ev_loop(loop, EVLOOP_ONESHOT);
0
- /* XXX: Need way to know when the loop is finished...
0
- * should return true or false */
0
-
0
   ev_timer_stop(loop, &timeout);
0
   
0
+ /* Call rb_thread_schedule() proportional to the number of rb threads running */
0
+ /* SO HACKY! Anyone have a better way to do this? */
0
+ int i;
0
+ for(i = 0; i < EBB_MAX_CLIENTS; i++)
0
+ if(server->clients[i].in_use)
0
+ rb_thread_schedule();
0
+
0
   if(server->open)
0
     return Qtrue;
0
   else

Comments

    No one has commented yet.