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
|
-
|
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(
|
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
|
-
|
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
|
-
//
|
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
|
}
|
data/lib/evdispatch/version.rb
CHANGED
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.
|
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;">→ ‘evdispatch’</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’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 – 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>
|
134
|
-
|
135
|
-
|
136
|
-
</li>
|
137
|
+
<li><h5>I get an error when installing the gem: <strong>“error: ‘curl_socket_t’ has not been
|
138
|
+
declared”</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’t happen on Linux and I’m actively looking into the
|
144
|
+
issue on my apple.</p>
|
145
|
+
</li>
|
137
146
|
</ul>
|
138
147
|
|
139
148
|
<h2>License</h2>
|