evdispatch 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ == 0.4.2 2008-05-17
2
+ * Prefetch from response Queue to reduce locking overhead
3
+ * Improve tests to auto run a daemonized test server
4
+
1
5
  == 0.4.1 2008-05-04
2
6
  * Avoid deleting request before it finishes enabling
3
7
  * Protect config.h with HAVE_CONFIG_H macro
@@ -330,23 +330,34 @@ Response *Dispatch::response_for( request_t id )
330
330
  return res;
331
331
  }
332
332
 
333
+ // expects lock on m_responses queue to be acquired
334
+ void Dispatch::pop_responses_into_response_table()
335
+ {
336
+ Response *res = NULL;
337
+ while( !m_responses.m_queue.empty() ) {
338
+ res = m_responses.m_queue.front();
339
+ m_responses.m_queue.pop();
340
+ m_responded[res->id] = res;
341
+ }
342
+ }
343
+
333
344
  Queue<Response>::POP_STATE Dispatch::wait_for_response_by_id( request_t id, Timer timeout )
334
345
  {
335
346
  // first check if the response is loaded
336
347
  Response *res = NULL;
337
348
  Queue<Response>::POP_STATE rstate;
338
- RespondedTable::iterator loc = m_responded.find(id);
339
349
 
350
+
351
+ // check in the local memory table
352
+ RespondedTable::iterator loc = m_responded.find(id);
340
353
  if( loc != m_responded.end() ){ return Queue<Response>::POPPED; }
341
354
 
342
- m_responses.m_lock.lock();
355
+ Guard lock(m_responses.m_lock);
343
356
 
344
357
  // see if we can get the response back
345
358
  std::queue<Response*>::size_type size = m_responses.m_queue.size();
346
359
  if( size > 0 ) {
347
- res = m_responses.m_queue.front();
348
- m_responses.m_queue.pop();
349
- m_responded[res->id] = res;
360
+ this->pop_responses_into_response_table();
350
361
  rstate = Queue<Response>::POPPED;
351
362
  }
352
363
  else {
@@ -354,9 +365,7 @@ Queue<Response>::POP_STATE Dispatch::wait_for_response_by_id( request_t id, Time
354
365
  timeout.update();
355
366
  m_responses.m_cond.timed_wait( m_responses.m_lock, timeout );
356
367
  if( size > 0 ) {
357
- res = m_responses.m_queue.front();
358
- m_responses.m_queue.pop();
359
- m_responded[res->id] = res;
368
+ this->pop_responses_into_response_table();
360
369
  rstate = Queue<Response>::POPPED;
361
370
  }
362
371
  else {
@@ -364,7 +373,6 @@ Queue<Response>::POP_STATE Dispatch::wait_for_response_by_id( request_t id, Time
364
373
  res = NULL;
365
374
  }
366
375
  }
367
- m_responses.m_lock.unlock();
368
376
 
369
377
  return rstate;
370
378
  }
@@ -259,6 +259,8 @@ namespace EVD {
259
259
 
260
260
  protected:
261
261
 
262
+ void pop_responses_into_response_table();
263
+
262
264
  struct ev_loop *m_loop;
263
265
 
264
266
  // this triggers a callback once every N milliseconds
@@ -6,16 +6,23 @@ TEST_PORT = 4044
6
6
  $req_count = 0
7
7
 
8
8
  class TestApp
9
-
9
+
10
10
  def initialize
11
- puts "Test server '#{__FILE__}', started"
11
+ instance_eval do
12
+ if $daemonized
13
+ def log(msg) ; end
14
+ else
15
+ def log(msg) ; puts msg ; end
16
+ end
17
+ end
18
+ log "Test server '#{__FILE__}', started"
12
19
  end
13
20
 
14
21
  def call(env)
15
22
  commands = env['PATH_INFO'].split('/')
16
23
  extras = {}
17
24
  $req_count += 1
18
- puts "#{$req_count} requests"
25
+ log "#{$req_count} requests"
19
26
 
20
27
  if commands.include?('delay')
21
28
  n = commands.last.to_f
@@ -38,7 +45,7 @@ class TestApp
38
45
  extras = {'Location' => "/redir/#{n-1}"}
39
46
  body = "redirect to redir #{n-1}"
40
47
  end
41
- puts body
48
+ log body
42
49
  status = 302
43
50
  elsif commands.include?('test_post_length')
44
51
  input_body = env['rack.input'].read
@@ -61,10 +68,17 @@ class TestApp
61
68
  [status, {'Content-Type' => 'text/json'}.merge(extras), body]
62
69
  end
63
70
  end
64
- # ebb's much better at handling concurrent requests use it if it's installed
65
- begin
66
- require 'ebb'
67
- Ebb.start_server(TestApp.new, :port => TEST_PORT)
68
- rescue LoadError => e
69
- Rack::Handler::Mongrel.run(TestApp.new, :Port => TEST_PORT )
71
+ if $0 == __FILE__
72
+ # ebb's much better at handling concurrent requests use it if it's installed
73
+ begin
74
+ require 'ebb'
75
+ if ARGV[0] == '-d'
76
+ require 'daemons'
77
+ $daemonized = true
78
+ Daemons.daemonize
79
+ end
80
+ Ebb.start_server(TestApp.new, :port => TEST_PORT)
81
+ rescue LoadError => e
82
+ Rack::Handler::Mongrel.run(TestApp.new, :Port => TEST_PORT )
83
+ end
70
84
  end
@@ -2,7 +2,7 @@ module Evdispatch #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 4
5
- TINY = 1
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
File without changes
File without changes
File without changes
File without changes
@@ -1,6 +1,9 @@
1
1
  require File.dirname(__FILE__) + '/test_helper.rb'
2
2
 
3
3
  class TestEvdispatch < Test::Unit::TestCase
4
+ def setup
5
+ TestServer.setup
6
+ end
4
7
 
5
8
  def test_streaming
6
9
  d = Evdispatch::Loop.new
@@ -4,3 +4,29 @@ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..','ext','revdis
4
4
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..','lib'))
5
5
 
6
6
  require 'evdispatch'
7
+
8
+ class TestServer
9
+ def self.setup
10
+ if !defined?($server_task)
11
+ require 'rubygems'
12
+ require 'daemons'
13
+
14
+ # start up the test server
15
+ require File.expand_path(File.join(File.dirname(__FILE__), '..','ext','revdispatch','server'))
16
+ $server_task = Daemons.call do
17
+ $daemonized = true
18
+ begin
19
+ require 'ebb'
20
+ Ebb.start_server(TestApp.new, :port => TEST_PORT)
21
+ rescue LoadError => e
22
+ Rack::Handler::Mongrel.run(TestApp.new, :Port => TEST_PORT )
23
+ end
24
+ end
25
+ sleep(0.5) # wait for the server to start up
26
+
27
+ at_exit {
28
+ $server_task.stop
29
+ }
30
+ end
31
+ end
32
+ end
@@ -18,7 +18,7 @@
18
18
  <h1>evdispatch</h1>
19
19
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/evdispatch"; return false'>
20
20
  <p>Get Version</p>
21
- <a href="http://rubyforge.org/projects/evdispatch" class="numbers">0.4.1</a>
21
+ <a href="http://rubyforge.org/projects/evdispatch" class="numbers">0.4.2</a>
22
22
  </div>
23
23
  <h4 style="float:right;padding-right:10px;">&#x2192; &#8216;evdispatch&#8217;</h4>
24
24
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evdispatch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd A. Fisher
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-15 00:00:00 -04:00
12
+ date: 2008-05-17 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -109,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  requirements: []
110
110
 
111
111
  rubyforge_project: evdispatch
112
- rubygems_version: 1.0.1
112
+ rubygems_version: 1.1.1
113
113
  signing_key:
114
114
  specification_version: 2
115
115
  summary: Based on libev provides a background event loop for making simulataneous requests