evdispatch 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +8 -0
- data/Manifest.txt +2 -1
- data/ext/revdispatch/libdispatch-0.1/Makefile.in +1 -1
- data/ext/revdispatch/libdispatch-0.1/src/ev_dispatch.cc +134 -41
- data/ext/revdispatch/libdispatch-0.1/src/ev_dispatch.h +4 -35
- data/ext/revdispatch/libdispatch-0.1/src/ev_http.cc +97 -17
- data/ext/revdispatch/libdispatch-0.1/src/ev_http.h +2 -0
- data/ext/revdispatch/libdispatch-0.1/test/Makefile.am +11 -1
- data/ext/revdispatch/libdispatch-0.1/test/Makefile.in +55 -3
- data/ext/revdispatch/libdispatch-0.1/test/key_test.cc +12 -12
- data/ext/revdispatch/libdispatch-0.1/test/next_test.cc +4 -4
- data/ext/revdispatch/libdispatch-0.1/test/pipe_test.cc +187 -39
- data/ext/revdispatch/libdispatch-0.1/test/post_test.cc +66 -0
- data/ext/revdispatch/libdispatch-0.1/test/stress_test.cc +62 -0
- data/ext/revdispatch/revdispatch.cc +96 -8
- data/ext/revdispatch/server.rb +5 -2
- data/ext/revdispatch/stest.rb +14 -8
- data/ext/revdispatch/test.rb +7 -3
- data/lib/evdispatch/loop.rb +4 -12
- data/lib/evdispatch/version.rb +1 -1
- data/test/test_evdispatch.rb +21 -33
- data/website/index.html +1 -1
- data/website/index.txt +12 -4
- metadata +4 -3
- data/ext/revdispatch/libdispatch-0.1/TODO +0 -5
@@ -24,14 +24,11 @@
|
|
24
24
|
* # start the event loop thread
|
25
25
|
*
|
26
26
|
* # send a dispatch http request and store a handle to the request
|
27
|
-
* google_id = d.
|
27
|
+
* google_id = d.request("http://www.google.com/")
|
28
28
|
*
|
29
29
|
* # do some processing and later on check for the response
|
30
|
-
*
|
31
|
-
*
|
32
|
-
* break if res
|
33
|
-
* end
|
34
|
-
* res = d.response_for( google_id ) unless res
|
30
|
+
*
|
31
|
+
* res = d.response( google_id )
|
35
32
|
*
|
36
33
|
* puts res[:body]
|
37
34
|
*
|
@@ -51,6 +48,12 @@
|
|
51
48
|
static VALUE rb_Evdispatch;
|
52
49
|
static VALUE rb_Loop;
|
53
50
|
|
51
|
+
/**
|
52
|
+
* call-seq:
|
53
|
+
* loop.start -> loop
|
54
|
+
*
|
55
|
+
* Starts up the background event loop
|
56
|
+
*/
|
54
57
|
static
|
55
58
|
VALUE Loop_start( VALUE self )
|
56
59
|
{
|
@@ -62,6 +65,12 @@ VALUE Loop_start( VALUE self )
|
|
62
65
|
return self;
|
63
66
|
}
|
64
67
|
|
68
|
+
/**
|
69
|
+
* call-seq:
|
70
|
+
* loop.request_http(url) -> request_id
|
71
|
+
*
|
72
|
+
* Notifies the background thread of a new request. Call this method to start a basic HTTP GET request.
|
73
|
+
*/
|
65
74
|
static
|
66
75
|
VALUE Loop_request_http( VALUE self, VALUE url )
|
67
76
|
{
|
@@ -77,7 +86,7 @@ VALUE Loop_request_http( VALUE self, VALUE url )
|
|
77
86
|
{\
|
78
87
|
VALUE obj = rb_hash_aref( options, ID2SYM(rb_intern(name)) ); \
|
79
88
|
if( !NIL_P(obj) ) {\
|
80
|
-
snprintf( VALUE_BUFFER, VALUE_BUFFER_SIZE, "%
|
89
|
+
snprintf( VALUE_BUFFER, VALUE_BUFFER_SIZE, "%ld", FIX2LONG(obj) );\
|
81
90
|
req->set_opt(name, VALUE_BUFFER);\
|
82
91
|
}\
|
83
92
|
}
|
@@ -90,6 +99,29 @@ VALUE Loop_request_http( VALUE self, VALUE url )
|
|
90
99
|
}\
|
91
100
|
}
|
92
101
|
|
102
|
+
/**
|
103
|
+
* call-seq:
|
104
|
+
* loop.request( url, options ) -> request_id
|
105
|
+
*
|
106
|
+
* Notify the background of a new request. Can send a few options to influence the request:
|
107
|
+
*
|
108
|
+
* options ( from libcurl ):
|
109
|
+
*
|
110
|
+
* :port: port to connect to host with
|
111
|
+
* :autoreferer: Pass a non-zero parameter to enable this. When enabled, libcurl will automatically set the Referer: field in requests where it follows a Location: redirect.
|
112
|
+
* :followlocation: A non-zero parameter tells the library to follow any Location: header that the server sends as part of an HTTP header.
|
113
|
+
* This means that the library will re-send the same request on the new location and follow new Location: headers all the way until no more such headers are returned. 'maxredirs' can be used to limit the number of redirects libcurl will follow.
|
114
|
+
* :maxredirs: Pass a long. The set number will be the redirection limit. If that many redirections have been followed, the next redirect will cause an error (CURLE_TOO_MANY_REDIRECTS). This option only makes sense if the CURLOPT_FOLLOWLOCATION is used at the same time. Added in 7.15.1: Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for an infinite number of redirects (which is the default)
|
115
|
+
* :referer: Pass a pointer to a zero terminated string as parameter. It will be used to set the Referer: header in the http request sent to the remote server. This can be used to fool servers or scripts. You can also set any custom header with CURLOPT_HTTPHEADER.
|
116
|
+
* :useragent: Pass a pointer to a zero terminated string as parameter. It will be used to set the User-Agent: header in the http request sent to the remote server. This can be used to fool servers or scripts. You can also set any custom header with CURLOPT_HTTPHEADER.
|
117
|
+
* :cookie: Pass a pointer to a zero terminated string as parameter. It will be used to set a cookie in the http request. The format of the string should be NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain.
|
118
|
+
* If you need to set multiple cookies, you need to set them all using a single option and thus you need to concatenate them all in one single string. Set multiple cookies in one string like this: "name1=content1; name2=content2;" etc.
|
119
|
+
* Note that this option sets the cookie header explictly in the outgoing request(s). If multiple requests are done due to authentication, followed redirections or similar, they will all get this cookie passed on.
|
120
|
+
* Using this option multiple times will only make the latest string override the previous ones.
|
121
|
+
*
|
122
|
+
* :post: Pass a string and sets CURLOPT_POST, CURLOPT_POSTFIELDSIZE, and CURLOPT_COPYPOSTFIELDS
|
123
|
+
*
|
124
|
+
*/
|
93
125
|
static
|
94
126
|
VALUE Loop_request( int argc, VALUE *argv, VALUE self )
|
95
127
|
{
|
@@ -115,6 +147,7 @@ VALUE Loop_request( int argc, VALUE *argv, VALUE self )
|
|
115
147
|
SET_STR_VAL("referer");
|
116
148
|
SET_STR_VAL("useragent");
|
117
149
|
SET_STR_VAL("cookie");
|
150
|
+
SET_STR_VAL("post");
|
118
151
|
|
119
152
|
return rb_int_new( d->request(req) );
|
120
153
|
}
|
@@ -128,7 +161,11 @@ VALUE Loop_wait_for_response( VALUE self, VALUE id, VALUE timeout_seconds, VALUE
|
|
128
161
|
|
129
162
|
Data_Get_Struct( self, EVD::Dispatch, d );
|
130
163
|
|
131
|
-
|
164
|
+
long seconds = FIX2LONG(timeout_seconds);
|
165
|
+
long nanoseconds = FIX2LONG(timeout_mseconds)*1000*1000;
|
166
|
+
//printf( "wait seconds %ld, nanoseconds %ld\n", seconds, nanoseconds );
|
167
|
+
|
168
|
+
rstate = d->wait_for_response_by_id( rid, EVD::Timer(seconds, nanoseconds) );
|
132
169
|
|
133
170
|
return rb_int_new(rstate);
|
134
171
|
}
|
@@ -160,6 +197,54 @@ VALUE Loop_response_for( VALUE self, VALUE id )
|
|
160
197
|
return Qnil;
|
161
198
|
}
|
162
199
|
|
200
|
+
static
|
201
|
+
VALUE Loop_blocking_response_for( int argc, VALUE *argv, VALUE self )
|
202
|
+
{
|
203
|
+
VALUE req_id, options;
|
204
|
+
EVD::Dispatch *dispatcher;
|
205
|
+
Data_Get_Struct( self, EVD::Dispatch, dispatcher );
|
206
|
+
|
207
|
+
// required 1 argument the 'url' and 1 optional the hash of options
|
208
|
+
if( rb_scan_args( argc, argv, "11", &req_id, &options ) == 1 ) {
|
209
|
+
options = rb_hash_new();
|
210
|
+
rb_hash_aset( options, ID2SYM(rb_intern("timeout")), rb_float_new( 2.0 ) );
|
211
|
+
}
|
212
|
+
|
213
|
+
EVD::request_t id = FIX2LONG(req_id);
|
214
|
+
VALUE timeout_value = rb_hash_aref( options, ID2SYM(rb_intern("timeout")) );
|
215
|
+
double timeout = RFLOAT( timeout_value )->value;
|
216
|
+
|
217
|
+
struct timeval start;
|
218
|
+
EVD::Timer::current_time(&start);
|
219
|
+
long int secs = (int)timeout;
|
220
|
+
long int msecs = (secs == 0) ? 500 : 0; // XXX: timer hack for small timeout
|
221
|
+
|
222
|
+
//printf( "waiting on id: %d, %d:%d\n", id, secs, msecs );
|
223
|
+
|
224
|
+
while( dispatcher->wait_for_response_by_id( id, EVD::Timer(secs,msecs*1000*1000) ) ) {
|
225
|
+
if( EVD::Timer::elapsed_time( &start ) > timeout ){
|
226
|
+
printf("exceeded max elasped time...\n");
|
227
|
+
break;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
EVD::HttpResponse *res = (EVD::HttpResponse *)dispatcher->response_for( id );
|
231
|
+
if( res ) {
|
232
|
+
|
233
|
+
VALUE result = rb_hash_new();
|
234
|
+
|
235
|
+
rb_hash_aset( result, ID2SYM(rb_intern("name")), rb_str_new( res->name.c_str(), res->name.length() ) );
|
236
|
+
rb_hash_aset( result, ID2SYM(rb_intern("body")), rb_str_new( res->body.c_str(), res->body.length() ) );
|
237
|
+
rb_hash_aset( result, ID2SYM(rb_intern("id")), rb_int_new( res->id ) );
|
238
|
+
rb_hash_aset( result, ID2SYM(rb_intern("response_time")), rb_float_new( res->response_time ) );
|
239
|
+
rb_hash_aset( result, ID2SYM(rb_intern("header")), rb_str_new( res->m_header.c_str(), res->m_header.length() ) );
|
240
|
+
|
241
|
+
delete res;
|
242
|
+
|
243
|
+
return result;
|
244
|
+
}
|
245
|
+
return Qnil;
|
246
|
+
}
|
247
|
+
|
163
248
|
static
|
164
249
|
VALUE Loop_flush( VALUE self )
|
165
250
|
{
|
@@ -177,12 +262,14 @@ VALUE Loop_stop( VALUE self )
|
|
177
262
|
Data_Get_Struct( self, EVD::Dispatch, d );
|
178
263
|
|
179
264
|
d->stop();
|
265
|
+
|
180
266
|
return Qnil;
|
181
267
|
}
|
182
268
|
|
183
269
|
static
|
184
270
|
void Loop_free( EVD::Dispatch *d )
|
185
271
|
{
|
272
|
+
fprintf(stderr,"Freeing loop\n");
|
186
273
|
delete d;
|
187
274
|
}
|
188
275
|
|
@@ -209,6 +296,7 @@ extern "C" void Init_revdispatch()
|
|
209
296
|
rb_define_method( rb_Loop, "request_http", (VALUE (*)(...))Loop_request_http, 1 );
|
210
297
|
rb_define_method( rb_Loop, "request", (VALUE (*)(...))Loop_request, -1 );
|
211
298
|
rb_define_method( rb_Loop, "flush", (VALUE (*)(...))Loop_flush, 0 );
|
299
|
+
rb_define_method( rb_Loop, "blocking_response_for", (VALUE (*)(...))Loop_blocking_response_for, -1 );
|
212
300
|
rb_define_method( rb_Loop, "response_for", (VALUE (*)(...))Loop_response_for, 1 );
|
213
301
|
rb_define_method( rb_Loop, "wait_for_response", (VALUE (*)(...))Loop_wait_for_response, 3 );
|
214
302
|
rb_define_method( rb_Loop, "stop", (VALUE (*)(...))Loop_stop, 0 );
|
data/ext/revdispatch/server.rb
CHANGED
@@ -5,15 +5,18 @@ Ebb.log = File.open('/dev/null','w')
|
|
5
5
|
|
6
6
|
TEST_PORT = 4044
|
7
7
|
|
8
|
+
$req_count = 0
|
8
9
|
|
9
10
|
class HelperApp
|
10
11
|
def call(env)
|
11
12
|
commands = env['PATH_INFO'].split('/')
|
12
13
|
extras = {}
|
14
|
+
$req_count += 1
|
15
|
+
puts "#{$req_count} requests"
|
13
16
|
|
14
17
|
if commands.include?('delay')
|
15
|
-
n = commands.last.
|
16
|
-
raise "delay called with n <= 0" if n < 0
|
18
|
+
n = commands.last.to_f
|
19
|
+
raise "delay called with n <= 0" if n < 0.0
|
17
20
|
sleep n
|
18
21
|
body = "delayed #{n} seconds"
|
19
22
|
status = 200
|
data/ext/revdispatch/stest.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
1
|
+
require 'test/unit'
|
2
2
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','..','lib')
|
3
4
|
require 'evdispatch'
|
4
|
-
require 'test/unit'
|
5
5
|
|
6
6
|
$d = Evdispatch::Loop.new
|
7
7
|
# start the event loop thread
|
@@ -29,15 +29,21 @@ class TestRequests < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_delayed_with_flush
|
32
|
-
id = $d.request("http://127.0.0.1:4044/delay/0")
|
33
|
-
tid = $d.request("http://127.0.0.1:4044/delay/3")
|
34
|
-
res = $d.
|
35
|
-
res2 = $d.
|
32
|
+
id = $d.request("http://127.0.0.1:4044/delay/0.1")
|
33
|
+
tid = $d.request("http://127.0.0.1:4044/delay/3.0")
|
34
|
+
res = $d.blocking_response_for( id, :timeout => 0.5 )
|
35
|
+
res2 = $d.blocking_response_for( tid, :timeout => 0.5 )#, 1.0, 1 )
|
36
36
|
if !res or !res2
|
37
37
|
$d.flush # flush because we aborted before we finished, still the issue of the request is still running, but any previous responses that were delayed will be flushed
|
38
38
|
end
|
39
|
-
|
40
|
-
|
39
|
+
assert_not_nil res
|
40
|
+
assert_nil res2
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_post
|
44
|
+
id = $d.request("http://127.0.0.1:4044/test_post_length", :post => "hello there world")
|
45
|
+
res = $d.blocking_response_for( id )
|
46
|
+
assert_not_nil res
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
data/ext/revdispatch/test.rb
CHANGED
@@ -16,14 +16,18 @@ require 'ostruct'
|
|
16
16
|
|
17
17
|
# NOTE: we define this part in ruby to make sure other ruby threads can execute while we wait
|
18
18
|
class Evdispatch::Loop
|
19
|
-
|
19
|
+
|
20
|
+
def response(id, timeout=2.0)
|
21
|
+
timer = Time.now
|
20
22
|
while wait_for_response( id, 1, 0 )
|
21
23
|
res = response_for( id )
|
22
24
|
break if res
|
25
|
+
break if( (Time.now - timer) > timeout )
|
23
26
|
end
|
24
27
|
res = response_for( id ) unless res
|
25
28
|
res
|
26
29
|
end
|
30
|
+
|
27
31
|
end
|
28
32
|
|
29
33
|
def request_bytes_from( d, base, amount, range )
|
@@ -58,11 +62,11 @@ def run_trial
|
|
58
62
|
|
59
63
|
# do some processing and later on check for the response
|
60
64
|
response = d.response( google_id )
|
61
|
-
puts "Requested: #{response[
|
65
|
+
puts "Requested: #{response[:name]} in #{Time.now - timer} seconds"
|
62
66
|
|
63
67
|
ebbbase = "http://127.0.0.1:4044/"
|
64
68
|
timer = Time.now
|
65
|
-
ids = request_bytes_from( d, ebbbase,
|
69
|
+
ids = request_bytes_from( d, ebbbase, 300, 10000 )
|
66
70
|
#ids += request_delay_from( d, ebbbase, 100, 1 )
|
67
71
|
|
68
72
|
# wait for each response
|
data/lib/evdispatch/loop.rb
CHANGED
@@ -4,21 +4,13 @@ require 'revdispatch'
|
|
4
4
|
# ruby threads can execute while we waiting for a response
|
5
5
|
module Evdispatch
|
6
6
|
class Loop
|
7
|
-
def response(id, timeout = 1.0
|
8
|
-
|
9
|
-
|
10
|
-
ms_i = ms.to_i
|
11
|
-
seconds = ms_i / 1000
|
12
|
-
mseconds = (ms - (seconds*1000)).to_i
|
13
|
-
#puts "Waiting #{seconds} seconds and #{mseconds} miliseconds"
|
14
|
-
|
15
|
-
while (wait_for_response( id, seconds, mseconds ) and attempts < max_attempts )
|
7
|
+
def response(id, timeout = 1.0)
|
8
|
+
timer = Time.now
|
9
|
+
while wait_for_response( id, 1, 0 )
|
16
10
|
res = response_for( id )
|
17
11
|
break if res
|
18
|
-
|
19
|
-
#puts "Attempt: #{attempts}"
|
12
|
+
break if( (Time.now - timer) > timeout )
|
20
13
|
end
|
21
|
-
return nil if !res and attempts == max_attempts
|
22
14
|
res = response_for( id ) unless res
|
23
15
|
res
|
24
16
|
end
|
data/lib/evdispatch/version.rb
CHANGED
data/test/test_evdispatch.rb
CHANGED
@@ -2,50 +2,40 @@ require File.dirname(__FILE__) + '/test_helper.rb'
|
|
2
2
|
|
3
3
|
class TestEvdispatch < Test::Unit::TestCase
|
4
4
|
|
5
|
-
def is_linux?
|
6
|
-
!(`uname`.grep(/linux/i)).empty?
|
7
|
-
end
|
8
|
-
|
9
5
|
def test_object_test
|
10
|
-
# start up the test server
|
11
|
-
if is_linux?
|
12
|
-
pid = fork do
|
13
|
-
require File.dirname(__FILE__) + '/../ext/revdispatch/server'
|
14
|
-
start_test_server
|
15
|
-
end
|
16
|
-
sleep 1
|
17
|
-
else
|
18
|
-
STDERR.puts "make sure '#{File.dirname(__FILE__) + '/../ext/revdispatch/server'} start' is running..."
|
19
|
-
end
|
20
|
-
|
21
6
|
d = Evdispatch::Loop.new
|
22
7
|
|
23
8
|
# start the event loop thread
|
24
9
|
d.start
|
25
10
|
|
26
|
-
|
11
|
+
# increase this to verify
|
12
|
+
1.times do
|
27
13
|
|
28
|
-
|
14
|
+
begin
|
29
15
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
16
|
+
ObjectSpace.garbage_collect
|
17
|
+
|
18
|
+
10.times do
|
19
|
+
begin
|
20
|
+
start_count = ObjectSpace.each_object { }
|
21
|
+
duration = run_trial(d, 100)
|
22
|
+
new_count = ObjectSpace.each_object { }
|
23
|
+
puts "10 trials: #{duration} seconds, new objects #{new_count - start_count}, #{new_count} - #{start_count}"
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
start_count = ObjectSpace.each_object { }
|
28
|
+
duration = run_trial(d, 200)
|
29
|
+
new_count = ObjectSpace.each_object { }
|
30
|
+
puts "100 trials: #{duration} seconds, new objects #{new_count - start_count}, #{new_count} - #{start_count}"
|
31
|
+
end
|
37
32
|
|
38
|
-
begin
|
39
|
-
start_count = ObjectSpace.each_object { }
|
40
|
-
duration = run_trial(d, 200)
|
41
|
-
new_count = ObjectSpace.each_object { }
|
42
|
-
puts "100 trials: #{duration} seconds, new objects #{new_count - start_count}, #{new_count} - #{start_count}"
|
43
33
|
end
|
44
34
|
|
35
|
+
rescue => e
|
36
|
+
puts e.message, e.backtrace
|
45
37
|
end
|
46
38
|
|
47
|
-
rescue => e
|
48
|
-
puts e.message, e.backtrace
|
49
39
|
end
|
50
40
|
|
51
41
|
count = ObjectSpace.each_object { }
|
@@ -57,8 +47,6 @@ class TestEvdispatch < Test::Unit::TestCase
|
|
57
47
|
|
58
48
|
# sometime later you can stop the event loop
|
59
49
|
d.stop
|
60
|
-
ensure
|
61
|
-
Process.kill('HUP', pid) if is_linux?
|
62
50
|
end
|
63
51
|
|
64
52
|
def request_bytes_from( d, base, amount, range )
|
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.2</a>
|
22
22
|
</div>
|
23
23
|
<h4 style="float:right;padding-right:10px;">→ ‘evdispatch’</h4>
|
24
24
|
|
data/website/index.txt
CHANGED
@@ -58,6 +58,9 @@ chances are high that the news_id will have returned it's response
|
|
58
58
|
by the time it gets finished with the blogs. This is because the background thread does not block while ruby waits for the first response.
|
59
59
|
One thing to keep in mind is the background thread will block if it has to resolve DNS names.
|
60
60
|
|
61
|
+
In my testing I've successfully run 3 million requests. Doing 10000 iterations of 300 concurrent requests, on a Linux FC7 duel P4 machine.
|
62
|
+
Memory utilization stays flat at around 14 to 19 megs with about 2,000 - 12,000 objects.
|
63
|
+
|
61
64
|
h2. Demonstration of usage
|
62
65
|
|
63
66
|
<pre syntax="ruby">
|
@@ -97,10 +100,15 @@ The trunk repository is <a href="http://evdispatch.rubyforge.org/svn/trunk/">htt
|
|
97
100
|
h2. F.A.Q.
|
98
101
|
|
99
102
|
<ul>
|
100
|
-
<li><h5>
|
101
|
-
|
102
|
-
|
103
|
-
</li>
|
103
|
+
<li><h5>I get an error when installing the gem: <strong>"error: 'curl_socket_t' has not been
|
104
|
+
declared"</strong></h5>
|
105
|
+
<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>
|
106
|
+
</li>
|
107
|
+
<li><h5>Mac OSX (Darwin) Crashing on HTTP POST request</h5>
|
108
|
+
<p>There are some issues with crashes on darwin builds when making an HTTP
|
109
|
+
POST. This doesn't happen on Linux and I'm actively looking into the
|
110
|
+
issue on my apple.</p>
|
111
|
+
</li>
|
104
112
|
</ul>
|
105
113
|
|
106
114
|
h2. License
|
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
|
+
version: 0.2.4
|
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-04-
|
12
|
+
date: 2008-04-16 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -69,7 +69,6 @@ files:
|
|
69
69
|
- ext/revdispatch/libdispatch-0.1/Makefile.am
|
70
70
|
- ext/revdispatch/libdispatch-0.1/Makefile.in
|
71
71
|
- ext/revdispatch/libdispatch-0.1/README
|
72
|
-
- ext/revdispatch/libdispatch-0.1/TODO
|
73
72
|
- ext/revdispatch/libdispatch-0.1/aclocal.m4
|
74
73
|
- ext/revdispatch/libdispatch-0.1/autogen.sh
|
75
74
|
- ext/revdispatch/libdispatch-0.1/config.guess
|
@@ -125,6 +124,8 @@ files:
|
|
125
124
|
- ext/revdispatch/libdispatch-0.1/test/next_test.cc
|
126
125
|
- ext/revdispatch/libdispatch-0.1/test/pipe_test.cc
|
127
126
|
- ext/revdispatch/libdispatch-0.1/test/opt_test.cc
|
127
|
+
- ext/revdispatch/libdispatch-0.1/test/post_test.cc
|
128
|
+
- ext/revdispatch/libdispatch-0.1/test/stress_test.cc
|
128
129
|
has_rdoc: true
|
129
130
|
homepage: http://evdispatch.rubyforge.org
|
130
131
|
post_install_message:
|