evdispatch 0.1.0
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 +3 -0
- data/License.txt +20 -0
- data/Manifest.txt +96 -0
- data/README.txt +73 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +15 -0
- data/ext/revdispatch/extconf.rb +31 -0
- data/ext/revdispatch/libevdispatch/Changelog +0 -0
- data/ext/revdispatch/libevdispatch/LICENSE +0 -0
- data/ext/revdispatch/libevdispatch/Makefile.am +10 -0
- data/ext/revdispatch/libevdispatch/Makefile.in +637 -0
- data/ext/revdispatch/libevdispatch/README +3 -0
- data/ext/revdispatch/libevdispatch/TODO +5 -0
- data/ext/revdispatch/libevdispatch/aclocal.m4 +7459 -0
- data/ext/revdispatch/libevdispatch/autogen.sh +11 -0
- data/ext/revdispatch/libevdispatch/confdefs.h +32 -0
- data/ext/revdispatch/libevdispatch/config.guess +1516 -0
- data/ext/revdispatch/libevdispatch/config.h.in +112 -0
- data/ext/revdispatch/libevdispatch/config.sub +1626 -0
- data/ext/revdispatch/libevdispatch/configure +21949 -0
- data/ext/revdispatch/libevdispatch/configure.ac +40 -0
- data/ext/revdispatch/libevdispatch/depcomp +584 -0
- data/ext/revdispatch/libevdispatch/install-sh +507 -0
- data/ext/revdispatch/libevdispatch/libev/Changes +54 -0
- data/ext/revdispatch/libevdispatch/libev/LICENSE +25 -0
- data/ext/revdispatch/libevdispatch/libev/Makefile.am +18 -0
- data/ext/revdispatch/libevdispatch/libev/Makefile.in +677 -0
- data/ext/revdispatch/libevdispatch/libev/README +130 -0
- data/ext/revdispatch/libevdispatch/libev/aclocal.m4 +7430 -0
- data/ext/revdispatch/libevdispatch/libev/autogen.sh +7 -0
- data/ext/revdispatch/libevdispatch/libev/config.guess +1516 -0
- data/ext/revdispatch/libevdispatch/libev/config.h.in +106 -0
- data/ext/revdispatch/libevdispatch/libev/config.sub +1626 -0
- data/ext/revdispatch/libevdispatch/libev/configure +21636 -0
- data/ext/revdispatch/libevdispatch/libev/configure.ac +18 -0
- data/ext/revdispatch/libevdispatch/libev/ev++.h +779 -0
- data/ext/revdispatch/libevdispatch/libev/ev.3 +3276 -0
- data/ext/revdispatch/libevdispatch/libev/ev.c +2547 -0
- data/ext/revdispatch/libevdispatch/libev/ev.h +608 -0
- data/ext/revdispatch/libevdispatch/libev/ev.pod +3192 -0
- data/ext/revdispatch/libevdispatch/libev/ev_epoll.c +182 -0
- data/ext/revdispatch/libevdispatch/libev/ev_kqueue.c +194 -0
- data/ext/revdispatch/libevdispatch/libev/ev_poll.c +135 -0
- data/ext/revdispatch/libevdispatch/libev/ev_port.c +163 -0
- data/ext/revdispatch/libevdispatch/libev/ev_select.c +244 -0
- data/ext/revdispatch/libevdispatch/libev/ev_vars.h +157 -0
- data/ext/revdispatch/libevdispatch/libev/ev_win32.c +125 -0
- data/ext/revdispatch/libevdispatch/libev/ev_wrap.h +144 -0
- data/ext/revdispatch/libevdispatch/libev/event.c +404 -0
- data/ext/revdispatch/libevdispatch/libev/event.h +152 -0
- data/ext/revdispatch/libevdispatch/libev/install-sh +294 -0
- data/ext/revdispatch/libevdispatch/libev/libev.m4 +28 -0
- data/ext/revdispatch/libevdispatch/libev/ltmain.sh +6930 -0
- data/ext/revdispatch/libevdispatch/libev/missing +336 -0
- data/ext/revdispatch/libevdispatch/libev/mkinstalldirs +111 -0
- data/ext/revdispatch/libevdispatch/ltmain.sh +6930 -0
- data/ext/revdispatch/libevdispatch/missing +367 -0
- data/ext/revdispatch/libevdispatch/src/Makefile.am +11 -0
- data/ext/revdispatch/libevdispatch/src/Makefile.in +486 -0
- data/ext/revdispatch/libevdispatch/src/ev_dispatch.cc +264 -0
- data/ext/revdispatch/libevdispatch/src/ev_dispatch.h +300 -0
- data/ext/revdispatch/libevdispatch/src/ev_http.cc +238 -0
- data/ext/revdispatch/libevdispatch/src/ev_http.h +65 -0
- data/ext/revdispatch/libevdispatch/test/Makefile.am +16 -0
- data/ext/revdispatch/libevdispatch/test/Makefile.in +513 -0
- data/ext/revdispatch/libevdispatch/test/helper.rb +94 -0
- data/ext/revdispatch/libevdispatch/test/key_test.cc +52 -0
- data/ext/revdispatch/libevdispatch/test/next_test.cc +86 -0
- data/ext/revdispatch/libevdispatch/test/next_test.rb +8 -0
- data/ext/revdispatch/libevdispatch/test/server.rb +9 -0
- data/ext/revdispatch/revdispatch.cc +151 -0
- data/ext/revdispatch/server.rb +60 -0
- data/ext/revdispatch/test.rb +100 -0
- data/lib/evdispatch/loop.rb +16 -0
- data/lib/evdispatch/version.rb +9 -0
- data/lib/evdispatch.rb +8 -0
- data/log/debug.log +0 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/extconf/revdispatch.rake +43 -0
- data/tasks/extconf.rake +13 -0
- data/tasks/website.rake +17 -0
- data/test/test_evdispatch.rb +11 -0
- data/test/test_helper.rb +3 -0
- data/test/test_revdispatch_extn.rb +14 -0
- data/website/index.html +128 -0
- data/website/index.txt +55 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +49 -0
- metadata +157 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#include "ev_dispatch.h"
|
|
2
|
+
|
|
3
|
+
using namespace EVD;
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// catch SIGINT to kill process
|
|
7
|
+
static void SIGINT_handler(int sig)
|
|
8
|
+
{
|
|
9
|
+
exit(sig);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static void run_tests( Dispatch &dispatcher, int count )
|
|
13
|
+
{
|
|
14
|
+
time_t start_time = time(NULL);
|
|
15
|
+
int expected_response_count = 0;
|
|
16
|
+
int response_count = 0;
|
|
17
|
+
|
|
18
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/bytes/10200/");
|
|
19
|
+
++expected_response_count;
|
|
20
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/bytes/10080/");
|
|
21
|
+
++expected_response_count;
|
|
22
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/delay/2/");
|
|
23
|
+
++expected_response_count;
|
|
24
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/bytes/100900/");
|
|
25
|
+
++expected_response_count;
|
|
26
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/delay/1/");
|
|
27
|
+
++expected_response_count;
|
|
28
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/delay/1/");
|
|
29
|
+
++expected_response_count;
|
|
30
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/delay/3/");
|
|
31
|
+
++expected_response_count;
|
|
32
|
+
dispatcher.request(Request::HTTP, "http://127.0.0.1:4044/bytes/1010/");
|
|
33
|
+
++expected_response_count;
|
|
34
|
+
|
|
35
|
+
//ev_sleep(0.2);
|
|
36
|
+
|
|
37
|
+
Response *rep = NULL;
|
|
38
|
+
Timer timeout(2,0);
|
|
39
|
+
double longest_request = 0.0;
|
|
40
|
+
|
|
41
|
+
while( expected_response_count > 0 && (rep = dispatcher.get_next_response(timeout)) ){
|
|
42
|
+
if( longest_request < rep->response_time ){
|
|
43
|
+
longest_request = rep->response_time;
|
|
44
|
+
}
|
|
45
|
+
printf( "recieved response(%d): from '%s', Content-Length: %d bytes, within: %.2f seconds \n", rep->id, rep->name.c_str(), rep->body.length(), rep->response_time );
|
|
46
|
+
++response_count;
|
|
47
|
+
delete rep;
|
|
48
|
+
--expected_response_count;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if( expected_response_count != 0 ){
|
|
52
|
+
printf( "Expected: %d responses but recieved: %d\n", expected_response_count, response_count );
|
|
53
|
+
}
|
|
54
|
+
printf( "%d responses completed, within %.2f seconds\n", response_count, difftime( time(NULL), start_time ) );
|
|
55
|
+
printf( "longest request: %.2f\n", longest_request );
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
int main(int argc, char **argv)
|
|
59
|
+
{
|
|
60
|
+
Dispatch dispatcher;
|
|
61
|
+
|
|
62
|
+
if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
|
|
63
|
+
printf("SIGINT install error\n");
|
|
64
|
+
exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if( !dispatcher.start() ){
|
|
68
|
+
fprintf( stderr, "Failed to start up dispatcher\n" );
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
printf( "dispatcher thread running...\n" );
|
|
73
|
+
|
|
74
|
+
time_t start_time = time(NULL);
|
|
75
|
+
|
|
76
|
+
run_tests( dispatcher, 10 );
|
|
77
|
+
run_tests( dispatcher, 10 );
|
|
78
|
+
run_tests( dispatcher, 10 );
|
|
79
|
+
run_tests( dispatcher, 10 );
|
|
80
|
+
|
|
81
|
+
printf( "total time: %.2f seconds\n", difftime( time(NULL), start_time ) );
|
|
82
|
+
|
|
83
|
+
dispatcher.stop();
|
|
84
|
+
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
test_dir = File.dirname(__FILE__)
|
|
2
|
+
require test_dir + '/helper'
|
|
3
|
+
puts "starting up ebb";
|
|
4
|
+
Thread.start{ Ebb.start_server(HelperApp.new, :port => TEST_PORT) }
|
|
5
|
+
sleep 0.1 until Ebb.running?
|
|
6
|
+
system("#{test_dir}/next_test")
|
|
7
|
+
Ebb.stop_server
|
|
8
|
+
sleep 0.1 while Ebb.running?
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include "ev_dispatch.h"
|
|
3
|
+
|
|
4
|
+
/* ruby 1.9 compat */
|
|
5
|
+
#ifndef RSTRING_PTR
|
|
6
|
+
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
#ifndef RSTRING_LEN
|
|
10
|
+
#define RSTRING_LEN(str) RSTRING(str)->len
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
*
|
|
16
|
+
* Using ruby dispatch interface:
|
|
17
|
+
*
|
|
18
|
+
* require 'rev_dispatch'
|
|
19
|
+
*
|
|
20
|
+
* # create a new dispatch loop
|
|
21
|
+
* d = Rev::Dispatch::Loop.new
|
|
22
|
+
*
|
|
23
|
+
* # start the event loop thread
|
|
24
|
+
*
|
|
25
|
+
* # send a dispatch http request and store a handle to the request
|
|
26
|
+
* google_id = d.request("get", "http://www.google.com/")
|
|
27
|
+
*
|
|
28
|
+
* # do some processing and later on check for the response
|
|
29
|
+
* while d.wait_for_response( google_id, 1, 0 )
|
|
30
|
+
* res = d.response_for( google_id )
|
|
31
|
+
* break if res
|
|
32
|
+
* end
|
|
33
|
+
* res = d.response_for( google_id ) unless res
|
|
34
|
+
*
|
|
35
|
+
* puts res.inspect # array of response values
|
|
36
|
+
*
|
|
37
|
+
* # sometime later you can stop the event loop
|
|
38
|
+
* d.stop
|
|
39
|
+
*
|
|
40
|
+
*
|
|
41
|
+
* You only get 1 background event loop, calling start multiple times will have no effect.
|
|
42
|
+
* You typically don't need or want to stop the event loop after it's active. It will sit in the
|
|
43
|
+
* background and happily wait for new requests using a minimal amount of cpu while waiting.
|
|
44
|
+
* Everything in the background thread is written in C++ and has absolutely no hooks back into ruby.
|
|
45
|
+
* The results of the work being processed in the background can be retrieved by ruby but that is it.
|
|
46
|
+
*/
|
|
47
|
+
static VALUE rb_Evdispatch;
|
|
48
|
+
static VALUE rb_Loop;
|
|
49
|
+
|
|
50
|
+
static
|
|
51
|
+
VALUE Loop_start( VALUE self )
|
|
52
|
+
{
|
|
53
|
+
EVD::Dispatch *d;
|
|
54
|
+
Data_Get_Struct( self, EVD::Dispatch, d );
|
|
55
|
+
|
|
56
|
+
d->start();
|
|
57
|
+
|
|
58
|
+
return self;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static
|
|
62
|
+
VALUE Loop_request_http( VALUE self, VALUE url )
|
|
63
|
+
{
|
|
64
|
+
EVD::Dispatch *d;
|
|
65
|
+
Data_Get_Struct( self, EVD::Dispatch, d );
|
|
66
|
+
|
|
67
|
+
EVD::request_t id = d->request( EVD::Request::HTTP, RSTRING_PTR(url) );
|
|
68
|
+
|
|
69
|
+
return rb_int_new(id);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static
|
|
73
|
+
VALUE Loop_wait_for_response( VALUE self, VALUE id, VALUE timeout_seconds, VALUE timeout_mseconds )
|
|
74
|
+
{
|
|
75
|
+
EVD::Dispatch *d;
|
|
76
|
+
EVD::Queue<EVD::Response>::POP_STATE rstate;
|
|
77
|
+
EVD::request_t rid = FIX2LONG(id);
|
|
78
|
+
|
|
79
|
+
Data_Get_Struct( self, EVD::Dispatch, d );
|
|
80
|
+
|
|
81
|
+
rstate = d->wait_for_response_by_id( rid, EVD::Timer(FIX2LONG(timeout_seconds), FIX2LONG(timeout_mseconds)) );
|
|
82
|
+
|
|
83
|
+
return rb_int_new(rstate);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static
|
|
87
|
+
VALUE Loop_response_for( VALUE self, VALUE id )
|
|
88
|
+
{
|
|
89
|
+
EVD::Dispatch *d;
|
|
90
|
+
Data_Get_Struct( self, EVD::Dispatch, d );
|
|
91
|
+
|
|
92
|
+
EVD::Response *res = NULL;
|
|
93
|
+
EVD::request_t rid = FIX2LONG(id);
|
|
94
|
+
|
|
95
|
+
res = d->response_for( rid );
|
|
96
|
+
if( res ){
|
|
97
|
+
|
|
98
|
+
VALUE result = rb_hash_new();
|
|
99
|
+
|
|
100
|
+
rb_hash_aset( result, ID2SYM(rb_intern("name")), rb_str_new( res->name.c_str(), res->name.length() ) );
|
|
101
|
+
rb_hash_aset( result, ID2SYM(rb_intern("body")), rb_str_new( res->body.c_str(), res->body.length() ) );
|
|
102
|
+
rb_hash_aset( result, ID2SYM(rb_intern("id")), rb_int_new( res->id ) );
|
|
103
|
+
rb_hash_aset( result, ID2SYM(rb_intern("response_time")), rb_float_new( res->response_time ) );
|
|
104
|
+
|
|
105
|
+
delete res;
|
|
106
|
+
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
return Qnil;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static
|
|
113
|
+
VALUE Loop_stop( VALUE self )
|
|
114
|
+
{
|
|
115
|
+
EVD::Dispatch *d;
|
|
116
|
+
Data_Get_Struct( self, EVD::Dispatch, d );
|
|
117
|
+
|
|
118
|
+
d->stop();
|
|
119
|
+
return Qnil;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static
|
|
123
|
+
void Loop_free( EVD::Dispatch *d )
|
|
124
|
+
{
|
|
125
|
+
delete d;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static
|
|
129
|
+
VALUE Loop_alloc(VALUE klass)
|
|
130
|
+
{
|
|
131
|
+
VALUE object;
|
|
132
|
+
EVD::Dispatch *d = new EVD::Dispatch();
|
|
133
|
+
|
|
134
|
+
object = Data_Wrap_Struct( klass, NULL, Loop_free, d );
|
|
135
|
+
|
|
136
|
+
return object;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
extern "C" void Init_revdispatch()
|
|
140
|
+
{
|
|
141
|
+
rb_Evdispatch = rb_define_module( "Evdispatch" );
|
|
142
|
+
rb_Loop = rb_define_class_under( rb_Evdispatch, "Loop", rb_cObject );
|
|
143
|
+
|
|
144
|
+
rb_define_alloc_func( rb_Loop, Loop_alloc );
|
|
145
|
+
|
|
146
|
+
rb_define_method( rb_Loop, "start", (VALUE (*)(...))Loop_start, 0 );
|
|
147
|
+
rb_define_method( rb_Loop, "request_http", (VALUE (*)(...))Loop_request_http, 1 );
|
|
148
|
+
rb_define_method( rb_Loop, "response_for", (VALUE (*)(...))Loop_response_for, 1 );
|
|
149
|
+
rb_define_method( rb_Loop, "wait_for_response", (VALUE (*)(...))Loop_wait_for_response, 3 );
|
|
150
|
+
rb_define_method( rb_Loop, "stop", (VALUE (*)(...))Loop_stop, 0 );
|
|
151
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'ebb'
|
|
3
|
+
|
|
4
|
+
Ebb.log = File.open('/dev/null','w')
|
|
5
|
+
|
|
6
|
+
TEST_PORT = 4044
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HelperApp
|
|
10
|
+
def call(env)
|
|
11
|
+
commands = env['PATH_INFO'].split('/')
|
|
12
|
+
|
|
13
|
+
if commands.include?('delay')
|
|
14
|
+
n = commands.last.to_i
|
|
15
|
+
raise "delay called with n <= 0" if n < 0
|
|
16
|
+
sleep n
|
|
17
|
+
body = "delayed #{n} seconds"
|
|
18
|
+
status = 200
|
|
19
|
+
|
|
20
|
+
elsif commands.include?('bytes')
|
|
21
|
+
n = commands.last.to_i
|
|
22
|
+
raise "bytes called with n <= 0" if n <= 0
|
|
23
|
+
body = "C"*n
|
|
24
|
+
status = 200
|
|
25
|
+
|
|
26
|
+
elsif commands.include?('test_post_length')
|
|
27
|
+
input_body = env['rack.input'].read
|
|
28
|
+
|
|
29
|
+
content_length_header = env['HTTP_CONTENT_LENGTH'].to_i
|
|
30
|
+
|
|
31
|
+
if content_length_header == input_body.length
|
|
32
|
+
body = "Content-Length matches input length"
|
|
33
|
+
status = 200
|
|
34
|
+
else
|
|
35
|
+
body = "Content-Length header is #{content_length_header} but body length is #{input_body.length}"
|
|
36
|
+
status = 500
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
else
|
|
40
|
+
status = 404
|
|
41
|
+
body = "Undefined url"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
[status, {'Content-Type' => 'text/json'}, body]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def start
|
|
49
|
+
puts "starting up ebb";
|
|
50
|
+
Thread.start{ Ebb.start_server(HelperApp.new, :port => TEST_PORT) }
|
|
51
|
+
sleep 0.1 until Ebb.running?
|
|
52
|
+
|
|
53
|
+
Signal.trap( "HUP" ){
|
|
54
|
+
Ebb.stop_server
|
|
55
|
+
sleep 0.1 while Ebb.running?
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# keep process alive
|
|
59
|
+
sleep 0.5 while Ebb.running?
|
|
60
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'evdispatch'
|
|
2
|
+
|
|
3
|
+
# to run this through valgrind run the server outside of this script
|
|
4
|
+
# i run this: valgrind --leak-check=full ~/project/ruby-valgrind-env/bin/ruby test.rb r
|
|
5
|
+
unless ARGV[0] == 'r'
|
|
6
|
+
pid = fork do
|
|
7
|
+
require 'server'
|
|
8
|
+
start
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'ostruct'
|
|
13
|
+
|
|
14
|
+
# NOTE: we define this part in ruby to make sure other ruby threads can execute while we wait
|
|
15
|
+
class Evdispatch::Loop
|
|
16
|
+
def response(id)
|
|
17
|
+
while wait_for_response( id, 1, 0 )
|
|
18
|
+
res = response_for( id )
|
|
19
|
+
break if res
|
|
20
|
+
end
|
|
21
|
+
res = response_for( id ) unless res
|
|
22
|
+
res
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def request_bytes_from( d, base, amount, range )
|
|
27
|
+
ids = []
|
|
28
|
+
amount.times do|i|
|
|
29
|
+
am = rand( range )
|
|
30
|
+
ids << d.request_http( base + "bytes/#{am}/" )
|
|
31
|
+
end
|
|
32
|
+
ids
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def request_delay_from( d, base, amount, delay )
|
|
36
|
+
ids = []
|
|
37
|
+
amount.times do|i|
|
|
38
|
+
am = rand( delay )
|
|
39
|
+
ids << d.request_http( base + "delay/#{delay}/" )
|
|
40
|
+
end
|
|
41
|
+
ids
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def run_trial
|
|
45
|
+
|
|
46
|
+
d = Evdispatch::Loop.new
|
|
47
|
+
|
|
48
|
+
# start the event loop thread
|
|
49
|
+
d.start
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
timer = Time.now
|
|
53
|
+
# send a dispatch http request and store a handle to the request
|
|
54
|
+
google_id = d.request_http("http://www.google.com/")
|
|
55
|
+
|
|
56
|
+
# do some processing and later on check for the response
|
|
57
|
+
response = d.response( google_id )
|
|
58
|
+
puts "Requested: #{response[0]} in #{Time.now - timer} seconds"
|
|
59
|
+
|
|
60
|
+
ebbbase = "http://127.0.0.1:4044/"
|
|
61
|
+
timer = Time.now
|
|
62
|
+
ids = request_bytes_from( d, ebbbase, 20, 1000 )
|
|
63
|
+
ids += request_delay_from( d, ebbbase, 20, 1 )
|
|
64
|
+
|
|
65
|
+
# wait for each response
|
|
66
|
+
puts "expecting #{ids.size} responses..."
|
|
67
|
+
ids.each do|id|
|
|
68
|
+
response = d.response( id )
|
|
69
|
+
#puts response[:name]
|
|
70
|
+
ObjectSpace.garbage_collect
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
puts "recieved #{ids.size} responses in #{Time.now - timer} seconds"
|
|
74
|
+
|
|
75
|
+
# sometime later you can stop the event loop
|
|
76
|
+
d.stop
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
sleep 1 unless ARGV[0] == 'r'
|
|
81
|
+
|
|
82
|
+
ObjectSpace.garbage_collect
|
|
83
|
+
|
|
84
|
+
count = ObjectSpace.each_object { }
|
|
85
|
+
puts "Starting Total objects: #{count}"
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
run_trial
|
|
89
|
+
rescue => e
|
|
90
|
+
puts e.message, e.backtrace
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
Process.kill('HUP', pid) unless ARGV[0] == 'r'
|
|
95
|
+
|
|
96
|
+
count = ObjectSpace.each_object { }
|
|
97
|
+
puts "Final Total objects: #{count}"
|
|
98
|
+
ObjectSpace.garbage_collect
|
|
99
|
+
count = ObjectSpace.each_object { }
|
|
100
|
+
puts "After garbage collection objects: #{count}"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'revdispatch'
|
|
2
|
+
|
|
3
|
+
# define this part in ruby to make sure other
|
|
4
|
+
# ruby threads can execute while we waiting for a response
|
|
5
|
+
module Evdispatch
|
|
6
|
+
class Loop
|
|
7
|
+
def response(id)
|
|
8
|
+
while wait_for_response( id, 1, 0 )
|
|
9
|
+
res = response_for( id )
|
|
10
|
+
break if res
|
|
11
|
+
end
|
|
12
|
+
res = response_for( id ) unless res
|
|
13
|
+
res
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/evdispatch.rb
ADDED
data/log/debug.log
ADDED
|
File without changes
|
data/script/console
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# File: script/console
|
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
|
4
|
+
|
|
5
|
+
libs = " -r irb/completion"
|
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/evdispatch.rb'}"
|
|
9
|
+
puts "Loading evdispatch gem"
|
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/destroy'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/generate'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
begin
|
|
5
|
+
require 'newgem'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
puts "\n\nGenerating the website requires the newgem RubyGem"
|
|
8
|
+
puts "Install: gem install newgem\n\n"
|
|
9
|
+
exit(1)
|
|
10
|
+
end
|
|
11
|
+
require 'redcloth'
|
|
12
|
+
require 'syntax/convertors/html'
|
|
13
|
+
require 'erb'
|
|
14
|
+
require File.dirname(__FILE__) + '/../lib/evdispatch/version.rb'
|
|
15
|
+
|
|
16
|
+
version = Evdispatch::VERSION::STRING
|
|
17
|
+
download = 'http://rubyforge.org/projects/evdispatch'
|
|
18
|
+
|
|
19
|
+
class Fixnum
|
|
20
|
+
def ordinal
|
|
21
|
+
# teens
|
|
22
|
+
return 'th' if (10..19).include?(self % 100)
|
|
23
|
+
# others
|
|
24
|
+
case self % 10
|
|
25
|
+
when 1: return 'st'
|
|
26
|
+
when 2: return 'nd'
|
|
27
|
+
when 3: return 'rd'
|
|
28
|
+
else return 'th'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class Time
|
|
34
|
+
def pretty
|
|
35
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def convert_syntax(syntax, source)
|
|
40
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if ARGV.length >= 1
|
|
44
|
+
src, template = ARGV
|
|
45
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
|
|
46
|
+
|
|
47
|
+
else
|
|
48
|
+
puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
|
|
49
|
+
exit!
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
template = ERB.new(File.open(template).read)
|
|
53
|
+
|
|
54
|
+
title = nil
|
|
55
|
+
body = nil
|
|
56
|
+
File.open(src) do |fsrc|
|
|
57
|
+
title_text = fsrc.readline
|
|
58
|
+
body_text = fsrc.read
|
|
59
|
+
syntax_items = []
|
|
60
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
|
61
|
+
ident = syntax_items.length
|
|
62
|
+
element, syntax, source = $1, $2, $3
|
|
63
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
|
64
|
+
"syntax-temp-#{ident}"
|
|
65
|
+
}
|
|
66
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
|
67
|
+
body = RedCloth.new(body_text).to_html
|
|
68
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
|
69
|
+
end
|
|
70
|
+
stat = File.stat(src)
|
|
71
|
+
created = stat.ctime
|
|
72
|
+
modified = stat.mtime
|
|
73
|
+
|
|
74
|
+
$stdout << template.result(binding)
|