evdispatch 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -162,26 +162,26 @@ void Dispatch::stop()
162
162
  printf( "EVD::Dispatch stopping...\n" );
163
163
  m_lock.lock();
164
164
  m_loop_started = false;
165
+ m_lock.unlock();
166
+
165
167
  m_cond.broadcast();
166
168
  m_requests.signal();
167
169
  m_responses.signal();
168
- m_lock.unlock();
169
170
 
170
171
  // send the message to unloop all
171
- {
172
+ /*{
172
173
  Guard g(m_lock);
173
174
  do {
174
175
  // unloop again
175
- printf( "main loop is waiting on the event loop to go down\n" );
176
- ev_unloop( m_loop, EVUNLOOP_ALL );
177
- if( m_loop_down ) { break; }
178
- ev_unref( m_loop ); // decrement the ref count
176
+ printf( "main loop is waiting on the event loop to go down: %d\n", ev_loop_count( m_loop ) );
177
+
179
178
  // sleep until the event loop tells us it's done
180
- m_cond.timed_wait(m_lock,Timer(1,0)); // wait until we're done
179
+ m_cond.timed_wait(m_lock,Timer(2,0)); // wait until we're done
181
180
  }while( !m_loop_down );
182
- }
181
+ }*/
182
+ ev_async_send( m_loop, &m_loop_ender ); // signal to the event loop it's time to stop
183
183
 
184
- printf( "okay, we're joining the thread\n" );
184
+ //printf( "okay, we're joining the thread\n" );
185
185
  pthread_join( m_tid, NULL );
186
186
  if( m_http_client ) {
187
187
  delete m_http_client;
@@ -247,6 +247,15 @@ void Dispatch::request_cb( struct ev_loop *loop, struct ev_async *w, int revents
247
247
 
248
248
  }
249
249
 
250
+ void Dispatch::shutdown_loop_cb( struct ev_loop *loop, struct ev_async *w, int revents )
251
+ {
252
+ // printf( "received the loop unref message\n" );
253
+ Dispatch *d = (Dispatch*)w->data;
254
+ ev_async_stop( d->m_loop, &(d->m_request_watcher) );
255
+ ev_async_stop( d->m_loop, &(d->m_loop_ender) );
256
+ ev_unloop( d->m_loop, EVUNLOOP_ALL );
257
+ }
258
+
250
259
  // the main event loop
251
260
  void Dispatch::event_loop_main()
252
261
  {
@@ -256,20 +265,29 @@ void Dispatch::event_loop_main()
256
265
  ev_async_init( &m_request_watcher, request_cb_start );
257
266
  ev_async_start( m_loop, &m_request_watcher );
258
267
 
268
+ m_loop_ender.data = this;
269
+ ev_async_init( &m_loop_ender, shutdown_loop_cb );
270
+ ev_async_start( m_loop, &m_loop_ender );
271
+ ev_unref( m_loop ); // don't include the ender in the ev_loop life count
272
+
259
273
  m_lock.lock();
260
274
  m_loop_started = true;
261
275
  m_loop_down = false;
262
276
  m_cond.signal(); // let the world know we're ready for them
263
277
  m_lock.unlock();
264
278
 
279
+ // printf( "loop running\n" );
265
280
  // start the main event loop
266
281
  ev_loop( m_loop, 0 );
267
- ev_async_stop( m_loop, &m_request_watcher );
282
+ // printf( "ev loop is done\n" );
283
+
284
+ // the shutdown sequence
268
285
  m_http_client->stop();
269
286
  ev_loop_destroy( m_loop );
270
287
 
288
+ // printf( "get the lock to shutdown\n" );
271
289
  m_lock.lock();
272
- printf( "let the world know the event loop is going down\n" );
290
+ // printf( "let the world know the event loop is going down\n" );
273
291
  m_loop_down = true;
274
292
  m_cond.signal(); // let the world know we're done
275
293
  m_lock.unlock();
@@ -247,6 +247,7 @@ namespace EVD {
247
247
 
248
248
  static void request_cb_start( struct ev_loop *loop, struct ev_async *w, int revents );
249
249
  void request_cb( struct ev_loop *loop, struct ev_async *w, int revents );
250
+ static void shutdown_loop_cb( struct ev_loop *loop, struct ev_async *w, int revents );
250
251
 
251
252
  bool store_response_for( request_t id );
252
253
 
@@ -257,7 +258,7 @@ namespace EVD {
257
258
  // this triggers a callback once every N milliseconds
258
259
  struct ev_timer m_clock;
259
260
 
260
- struct ev_async m_request_watcher;
261
+ struct ev_async m_request_watcher, m_loop_ender;
261
262
 
262
263
  pid_t m_pid;
263
264
  pthread_t m_tid;
@@ -20,28 +20,28 @@ static void multi_error_report(CURLMcode rc)
20
20
  {
21
21
  switch(rc) {
22
22
  case CURLM_CALL_MULTI_PERFORM:
23
- printf("curlm:perform\n");
23
+ printf("curlm:perform: %s\n", curl_multi_strerror(rc) );
24
24
  break;
25
25
  case CURLM_OK:
26
26
  // printf("curlm:ok\n");
27
27
  break;
28
28
  case CURLM_BAD_HANDLE:
29
- printf("curlm:bad handle\n");
29
+ printf("curlm:bad handle: %s\n", curl_multi_strerror(rc) );
30
30
  break;
31
31
  case CURLM_BAD_EASY_HANDLE:
32
- printf("curlm:bad easy handle\n");
32
+ printf("curlm:bad easy handle: %s\n", curl_multi_strerror(rc) );
33
33
  break;
34
34
  case CURLM_OUT_OF_MEMORY:
35
- printf("curlm:oh shit out of memory\n");
35
+ printf("curlm:oh shit out of memory: %s\n", curl_multi_strerror(rc) );
36
36
  break;
37
37
  case CURLM_INTERNAL_ERROR:
38
- printf("curlm:oh shit internal error\n");
38
+ printf("curlm:oh shit internal error: %s\n", curl_multi_strerror(rc) );
39
39
  break;
40
40
  case CURLM_BAD_SOCKET:
41
- printf("curlm:bad socket\n");
41
+ printf("curlm:bad socket: %s\n", curl_multi_strerror(rc) );
42
42
  break;
43
43
  case CURLM_UNKNOWN_OPTION:
44
- printf("curlm:unknown option\n");
44
+ printf("curlm:unknown option: %s\n", curl_multi_strerror(rc) );
45
45
  break;
46
46
  }
47
47
  }
@@ -103,7 +103,7 @@ int HttpClient::sock_cb(CURL *e, curl_socket_t sock, int action, void *cbp, void
103
103
  switch( action ){
104
104
  case CURL_POLL_REMOVE: // (4) unregister
105
105
  // make sure we clear it out
106
- // printf( " del sock: 0x%X\n", sockinfo );
106
+ //printf( " del sock: 0x%X\n", sockinfo );
107
107
  curl_multi_assign(client->m_handle, sock, NULL);
108
108
  sockinfo->finish();
109
109
  delete sockinfo;
@@ -161,9 +161,11 @@ int HttpClient::update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
161
161
  ev_timer_start( client->m_disp->get_loop(), &(client->m_timer) );
162
162
  }
163
163
  else {
164
+ //printf( "start up http client timer\n" );
164
165
  ev_timer_init( &(client->m_timer), timeout_cb, timeout, timeout );
165
166
  client->m_timer.data = client;
166
167
  ev_timer_start( client->m_disp->get_loop(), &(client->m_timer) );
168
+ client->m_timer_set = true;
167
169
  }
168
170
 
169
171
  return 0;
@@ -221,6 +223,14 @@ void HttpClient::check_handles()
221
223
  }
222
224
 
223
225
  } while( easy );
226
+
227
+ if( msgs_left == 0 && m_timer_set ) {
228
+ // stop the event timer
229
+ //printf( "stop http client timer, no pending requests\n" );
230
+ ev_timer_stop( m_disp->get_loop(), &m_timer );
231
+ m_timer_set = false;
232
+ }
233
+
224
234
  }
225
235
 
226
236
  // CURLOPT_WRITEFUNCTION
@@ -307,7 +317,8 @@ bool HttpRequest::enable()
307
317
  rc = curl_multi_socket_all( m_client->m_handle, &m_client->m_active );
308
318
  } while( rc == CURLM_CALL_MULTI_PERFORM && m_client );
309
319
  }
310
-
320
+ // XXX: it's really strange that m_client could be 0x0 all of a sudden here... but that's currently what must be happening
321
+ // in order for the final return code to be CURLM_CALL_MULTI_PERFORM.
311
322
  if( m_client ) {
312
323
  m_client->check_handles();
313
324
  }
@@ -2,7 +2,7 @@ module Evdispatch #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 4
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/website/index.html CHANGED
@@ -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.2.2</a>
21
+ <a href="http://rubyforge.org/projects/evdispatch" class="numbers">0.2.4</a>
22
22
  </div>
23
23
  <h4 style="float:right;padding-right:10px;">&#x2192; &#8216;evdispatch&#8217;</h4>
24
24
 
@@ -84,6 +84,10 @@ by the time it gets finished with the blogs. This is because the background thre
84
84
  One thing to keep in mind is the background thread will block if it has to resolve <span class="caps">DNS</span> names.</p>
85
85
 
86
86
 
87
+ <p>In my testing I&#8217;ve successfully run 3 million requests. Doing 10000 iterations of 300 concurrent requests, on a Linux <span class="caps">FC7</span> duel P4 machine.
88
+ Memory utilization stays flat at around 14 to 19 megs with about 2,000 &#8211; 12,000 objects.</p>
89
+
90
+
87
91
  <h2>Demonstration of usage</h2>
88
92
 
89
93
 
@@ -130,10 +134,15 @@ One thing to keep in mind is the background thread will block if it has to resol
130
134
 
131
135
 
132
136
  <ul>
133
- <li><h5> I get an error when installing the gem: <strong>&#8220;error: &#8216;curl_socket_t&#8217; has not been
134
- declared&#8221;</strong></h5>
135
- <p> You need to have at least version 7.16 of <a href="http://curl.haxx.se/download.html">libcurl</a>. I recommend at least version: 7.18.1.</p>
136
- </li>
137
+ <li><h5>I get an error when installing the gem: <strong>&#8220;error: &#8216;curl_socket_t&#8217; has not been
138
+ declared&#8221;</strong></h5>
139
+ <p> You need to have at least version 7.17.1 of <a href="http://curl.haxx.se/download.html">libcurl</a>. I recommend at least version: 7.18.1.</p>
140
+ </li>
141
+ <li><h5>Mac <span class="caps">OSX</span> (Darwin) Crashing on <span class="caps">HTTP POST</span> request</h5>
142
+ <p>There are some issues with crashes on darwin builds when making an <span class="caps">HTTP</span>
143
+ <span class="caps">POST</span>. This doesn&#8217;t happen on Linux and I&#8217;m actively looking into the
144
+ issue on my apple.</p>
145
+ </li>
137
146
  </ul>
138
147
 
139
148
  <h2>License</h2>
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.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd A. Fisher