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
@@ -37,7 +37,7 @@ POST_UNINSTALL = :
|
|
37
37
|
build_triplet = @build@
|
38
38
|
host_triplet = @host@
|
39
39
|
bin_PROGRAMS = next_test$(EXEEXT) key_test$(EXEEXT) pipe_test$(EXEEXT) \
|
40
|
-
opt_test$(EXEEXT)
|
40
|
+
opt_test$(EXEEXT) post_test$(EXEEXT) stress_test$(EXEEXT)
|
41
41
|
subdir = test
|
42
42
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
43
43
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
@@ -63,6 +63,12 @@ opt_test_DEPENDENCIES =
|
|
63
63
|
am_pipe_test_OBJECTS = pipe_test-pipe_test.$(OBJEXT)
|
64
64
|
pipe_test_OBJECTS = $(am_pipe_test_OBJECTS)
|
65
65
|
pipe_test_DEPENDENCIES =
|
66
|
+
am_post_test_OBJECTS = post_test-post_test.$(OBJEXT)
|
67
|
+
post_test_OBJECTS = $(am_post_test_OBJECTS)
|
68
|
+
post_test_DEPENDENCIES =
|
69
|
+
am_stress_test_OBJECTS = stress_test-stress_test.$(OBJEXT)
|
70
|
+
stress_test_OBJECTS = $(am_stress_test_OBJECTS)
|
71
|
+
stress_test_DEPENDENCIES =
|
66
72
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
67
73
|
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
68
74
|
am__depfiles_maybe = depfiles
|
@@ -75,9 +81,11 @@ CXXLD = $(CXX)
|
|
75
81
|
CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
76
82
|
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
77
83
|
SOURCES = $(key_test_SOURCES) $(next_test_SOURCES) $(opt_test_SOURCES) \
|
78
|
-
$(pipe_test_SOURCES)
|
84
|
+
$(pipe_test_SOURCES) $(post_test_SOURCES) \
|
85
|
+
$(stress_test_SOURCES)
|
79
86
|
DIST_SOURCES = $(key_test_SOURCES) $(next_test_SOURCES) \
|
80
|
-
$(opt_test_SOURCES) $(pipe_test_SOURCES)
|
87
|
+
$(opt_test_SOURCES) $(pipe_test_SOURCES) $(post_test_SOURCES) \
|
88
|
+
$(stress_test_SOURCES)
|
81
89
|
ETAGS = etags
|
82
90
|
CTAGS = ctags
|
83
91
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
@@ -197,6 +205,14 @@ opt_test_SOURCES = opt_test.cc
|
|
197
205
|
opt_test_CPPFLAGS = -I$(top_srcdir)/src/ -I$(LIBEV_PATH)
|
198
206
|
opt_test_LDADD = -ldispatch -lev
|
199
207
|
opt_test_LDFLAGS = -L$(top_srcdir)/src/.libs/ `curl-config --libs` -L$(LIBEV_PATH)/.libs/
|
208
|
+
post_test_SOURCES = post_test.cc
|
209
|
+
post_test_CPPFLAGS = -I$(top_srcdir)/src/ -I$(LIBEV_PATH)
|
210
|
+
post_test_LDADD = -ldispatch -lev
|
211
|
+
post_test_LDFLAGS = -L$(top_srcdir)/src/.libs/ `curl-config --libs` -L$(LIBEV_PATH)/.libs/
|
212
|
+
stress_test_SOURCES = stress_test.cc
|
213
|
+
stress_test_CPPFLAGS = -I$(top_srcdir)/src/ -I$(LIBEV_PATH)
|
214
|
+
stress_test_LDADD = -ldispatch -lev
|
215
|
+
stress_test_LDFLAGS = -L$(top_srcdir)/src/.libs/ `curl-config --libs` -L$(LIBEV_PATH)/.libs/
|
200
216
|
all: all-am
|
201
217
|
|
202
218
|
.SUFFIXES:
|
@@ -270,6 +286,12 @@ opt_test$(EXEEXT): $(opt_test_OBJECTS) $(opt_test_DEPENDENCIES)
|
|
270
286
|
pipe_test$(EXEEXT): $(pipe_test_OBJECTS) $(pipe_test_DEPENDENCIES)
|
271
287
|
@rm -f pipe_test$(EXEEXT)
|
272
288
|
$(CXXLINK) $(pipe_test_LDFLAGS) $(pipe_test_OBJECTS) $(pipe_test_LDADD) $(LIBS)
|
289
|
+
post_test$(EXEEXT): $(post_test_OBJECTS) $(post_test_DEPENDENCIES)
|
290
|
+
@rm -f post_test$(EXEEXT)
|
291
|
+
$(CXXLINK) $(post_test_LDFLAGS) $(post_test_OBJECTS) $(post_test_LDADD) $(LIBS)
|
292
|
+
stress_test$(EXEEXT): $(stress_test_OBJECTS) $(stress_test_DEPENDENCIES)
|
293
|
+
@rm -f stress_test$(EXEEXT)
|
294
|
+
$(CXXLINK) $(stress_test_LDFLAGS) $(stress_test_OBJECTS) $(stress_test_LDADD) $(LIBS)
|
273
295
|
|
274
296
|
mostlyclean-compile:
|
275
297
|
-rm -f *.$(OBJEXT)
|
@@ -281,6 +303,8 @@ distclean-compile:
|
|
281
303
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/next_test-next_test.Po@am__quote@
|
282
304
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_test-opt_test.Po@am__quote@
|
283
305
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipe_test-pipe_test.Po@am__quote@
|
306
|
+
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/post_test-post_test.Po@am__quote@
|
307
|
+
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stress_test-stress_test.Po@am__quote@
|
284
308
|
|
285
309
|
.cc.o:
|
286
310
|
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
|
@@ -359,6 +383,34 @@ pipe_test-pipe_test.obj: pipe_test.cc
|
|
359
383
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
360
384
|
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pipe_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pipe_test-pipe_test.obj `if test -f 'pipe_test.cc'; then $(CYGPATH_W) 'pipe_test.cc'; else $(CYGPATH_W) '$(srcdir)/pipe_test.cc'; fi`
|
361
385
|
|
386
|
+
post_test-post_test.o: post_test.cc
|
387
|
+
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(post_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT post_test-post_test.o -MD -MP -MF "$(DEPDIR)/post_test-post_test.Tpo" -c -o post_test-post_test.o `test -f 'post_test.cc' || echo '$(srcdir)/'`post_test.cc; \
|
388
|
+
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/post_test-post_test.Tpo" "$(DEPDIR)/post_test-post_test.Po"; else rm -f "$(DEPDIR)/post_test-post_test.Tpo"; exit 1; fi
|
389
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='post_test.cc' object='post_test-post_test.o' libtool=no @AMDEPBACKSLASH@
|
390
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
391
|
+
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(post_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o post_test-post_test.o `test -f 'post_test.cc' || echo '$(srcdir)/'`post_test.cc
|
392
|
+
|
393
|
+
post_test-post_test.obj: post_test.cc
|
394
|
+
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(post_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT post_test-post_test.obj -MD -MP -MF "$(DEPDIR)/post_test-post_test.Tpo" -c -o post_test-post_test.obj `if test -f 'post_test.cc'; then $(CYGPATH_W) 'post_test.cc'; else $(CYGPATH_W) '$(srcdir)/post_test.cc'; fi`; \
|
395
|
+
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/post_test-post_test.Tpo" "$(DEPDIR)/post_test-post_test.Po"; else rm -f "$(DEPDIR)/post_test-post_test.Tpo"; exit 1; fi
|
396
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='post_test.cc' object='post_test-post_test.obj' libtool=no @AMDEPBACKSLASH@
|
397
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
398
|
+
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(post_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o post_test-post_test.obj `if test -f 'post_test.cc'; then $(CYGPATH_W) 'post_test.cc'; else $(CYGPATH_W) '$(srcdir)/post_test.cc'; fi`
|
399
|
+
|
400
|
+
stress_test-stress_test.o: stress_test.cc
|
401
|
+
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stress_test-stress_test.o -MD -MP -MF "$(DEPDIR)/stress_test-stress_test.Tpo" -c -o stress_test-stress_test.o `test -f 'stress_test.cc' || echo '$(srcdir)/'`stress_test.cc; \
|
402
|
+
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/stress_test-stress_test.Tpo" "$(DEPDIR)/stress_test-stress_test.Po"; else rm -f "$(DEPDIR)/stress_test-stress_test.Tpo"; exit 1; fi
|
403
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='stress_test.cc' object='stress_test-stress_test.o' libtool=no @AMDEPBACKSLASH@
|
404
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
405
|
+
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stress_test-stress_test.o `test -f 'stress_test.cc' || echo '$(srcdir)/'`stress_test.cc
|
406
|
+
|
407
|
+
stress_test-stress_test.obj: stress_test.cc
|
408
|
+
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stress_test-stress_test.obj -MD -MP -MF "$(DEPDIR)/stress_test-stress_test.Tpo" -c -o stress_test-stress_test.obj `if test -f 'stress_test.cc'; then $(CYGPATH_W) 'stress_test.cc'; else $(CYGPATH_W) '$(srcdir)/stress_test.cc'; fi`; \
|
409
|
+
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/stress_test-stress_test.Tpo" "$(DEPDIR)/stress_test-stress_test.Po"; else rm -f "$(DEPDIR)/stress_test-stress_test.Tpo"; exit 1; fi
|
410
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='stress_test.cc' object='stress_test-stress_test.obj' libtool=no @AMDEPBACKSLASH@
|
411
|
+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
412
|
+
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stress_test-stress_test.obj `if test -f 'stress_test.cc'; then $(CYGPATH_W) 'stress_test.cc'; else $(CYGPATH_W) '$(srcdir)/stress_test.cc'; fi`
|
413
|
+
|
362
414
|
mostlyclean-libtool:
|
363
415
|
-rm -f *.lo
|
364
416
|
|
@@ -26,26 +26,26 @@ int main(int argc, char **argv)
|
|
26
26
|
|
27
27
|
printf( "dispatcher thread running...\n" );
|
28
28
|
|
29
|
-
request_t
|
30
|
-
request_t
|
31
|
-
printf("
|
32
|
-
printf("
|
29
|
+
request_t id1 = dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/1000" ) );
|
30
|
+
request_t id2 = dispatcher.request(new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/10" ) );
|
31
|
+
printf("1: %d\n", id1);
|
32
|
+
printf("2: %d\n", id2);
|
33
33
|
|
34
34
|
Response *res = NULL;
|
35
35
|
|
36
|
-
while( dispatcher.wait_for_response_by_id(
|
37
|
-
printf("waiting for
|
36
|
+
while( dispatcher.wait_for_response_by_id( id1, Timer(1,5) ) ){
|
37
|
+
printf("waiting for 1...\n");
|
38
38
|
}
|
39
|
-
res = dispatcher.response_for(
|
40
|
-
printf("Recieved response from
|
39
|
+
res = dispatcher.response_for( id1 );
|
40
|
+
printf("Recieved response from 1: %s, Content-Length: %d\n", res->name.c_str(), res->body.length() );
|
41
41
|
delete res;
|
42
42
|
|
43
|
-
while( dispatcher.wait_for_response_by_id(
|
44
|
-
printf("waiting for
|
43
|
+
while( dispatcher.wait_for_response_by_id( id2, Timer(1,5) ) ){
|
44
|
+
printf("waiting for 2...\n");
|
45
45
|
}
|
46
46
|
|
47
|
-
res = dispatcher.response_for(
|
48
|
-
printf("Recieved response from
|
47
|
+
res = dispatcher.response_for( id2 );
|
48
|
+
printf("Recieved response from 2: %s, Content-Length: %d\n", res->name.c_str(), res->body.length() );
|
49
49
|
delete res;
|
50
50
|
|
51
51
|
return 0;
|
@@ -19,11 +19,11 @@ static void run_tests( Dispatch &dispatcher, int count )
|
|
19
19
|
|
20
20
|
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/10200/" ) );
|
21
21
|
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/10080/" ) );
|
22
|
-
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/2/" ) );
|
22
|
+
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/0.2/" ) );
|
23
23
|
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/100900/" ) );
|
24
|
-
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/1/" ) );
|
25
|
-
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/1/" ) );
|
26
|
-
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/3/" ) );
|
24
|
+
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/0.1/" ) );
|
25
|
+
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/0.1/" ) );
|
26
|
+
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/delay/0.3/" ) );
|
27
27
|
dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/1010/" ) );
|
28
28
|
int expected_response_count = 8 ;
|
29
29
|
|
@@ -1,67 +1,215 @@
|
|
1
|
+
#include <ext/hash_map>
|
2
|
+
#include <algorithm>
|
1
3
|
#include "ev_dispatch.h"
|
2
4
|
#include "ev_http.h"
|
3
5
|
#include <sys/select.h>
|
4
6
|
#include <errno.h>
|
5
7
|
|
8
|
+
// NOTE:
|
9
|
+
// this test could be written to use libev and it's event loop, however because this
|
10
|
+
// library may be used in ruby it might be desireable to have a select example that could
|
11
|
+
// be easy used within ruby language
|
12
|
+
//
|
13
|
+
// NOTE:
|
14
|
+
// because this example uses a pipe there only about 400-500 conncurrent connections can be used.
|
15
|
+
|
16
|
+
typedef __gnu_cxx::hash_map<int, struct ResponseDelegate* > ResponseTable;
|
17
|
+
|
6
18
|
using namespace EVD;
|
7
19
|
|
20
|
+
struct ResponseDelegate {
|
8
21
|
|
9
|
-
|
10
|
-
|
11
|
-
{
|
12
|
-
exit(sig);
|
13
|
-
}
|
22
|
+
ResponseDelegate();
|
23
|
+
~ResponseDelegate();
|
14
24
|
|
15
|
-
|
16
|
-
{
|
17
|
-
time_t start_time = time(NULL);
|
18
|
-
int response_count = 0;
|
19
|
-
int pfd[2];
|
25
|
+
void set_response( HttpResponse *ptr );
|
20
26
|
|
21
|
-
|
22
|
-
perror("pipe");
|
23
|
-
return;
|
24
|
-
}
|
27
|
+
bool init();
|
25
28
|
|
26
|
-
|
27
|
-
HttpRequest *req = new HttpRequest( dispatcher, "http://www.google.com/", pfd[1] );
|
28
|
-
HttpResponse *res = req->m_response;
|
29
|
+
void finish();
|
29
30
|
|
30
|
-
|
31
|
+
HttpResponse *m_response;
|
32
|
+
int m_pfd[2];
|
33
|
+
|
34
|
+
};
|
31
35
|
|
32
|
-
|
36
|
+
struct ResponseManager {
|
37
|
+
static const int READ_SIZE = 1024;
|
38
|
+
ResponseManager();
|
39
|
+
~ResponseManager();
|
40
|
+
|
41
|
+
void watch_response( ResponseDelegate *rd );
|
42
|
+
|
43
|
+
void reset();
|
44
|
+
|
45
|
+
bool process();
|
46
|
+
private:
|
33
47
|
int retval;
|
34
48
|
fd_set rd, wr, er;
|
35
49
|
struct timeval tv;
|
36
|
-
|
37
|
-
|
38
|
-
std::
|
50
|
+
char READ_BUFFER[READ_SIZE];
|
51
|
+
int max_fd;
|
52
|
+
std::vector<int> set_fds;
|
53
|
+
ResponseTable response_table;
|
54
|
+
};
|
55
|
+
|
39
56
|
|
57
|
+
ResponseManager::ResponseManager()
|
58
|
+
{
|
59
|
+
reset();
|
60
|
+
}
|
61
|
+
ResponseManager::~ResponseManager()
|
62
|
+
{
|
63
|
+
}
|
64
|
+
void ResponseManager::reset()
|
65
|
+
{
|
66
|
+
memset(READ_BUFFER, '\0', READ_SIZE);
|
40
67
|
FD_ZERO(&rd);
|
41
68
|
FD_ZERO(&wr);
|
42
69
|
FD_ZERO(&er);
|
43
|
-
FD_SET(pfd[0], &rd);
|
44
70
|
tv.tv_sec = 1;
|
45
71
|
tv.tv_usec = 0;
|
72
|
+
max_fd = 0;
|
73
|
+
}
|
46
74
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
75
|
+
void ResponseManager::watch_response( ResponseDelegate *res_del )
|
76
|
+
{
|
77
|
+
int fd = res_del->m_pfd[0];
|
78
|
+
FD_SET(fd, &rd);
|
79
|
+
if( fd > max_fd ){ max_fd = fd; }
|
80
|
+
set_fds.push_back( fd );
|
81
|
+
response_table[ fd ] = res_del;
|
82
|
+
std::sort(set_fds.begin(),set_fds.end());
|
83
|
+
}
|
84
|
+
|
85
|
+
bool ResponseManager::process()
|
86
|
+
{
|
87
|
+
int finished_count = 0;
|
88
|
+
|
89
|
+
while( !set_fds.empty() ) {
|
90
|
+
this->reset();
|
91
|
+
for( std::vector<int>::iterator i = set_fds.begin(); i != set_fds.end(); ++i ) {
|
92
|
+
int fd = *i;
|
93
|
+
FD_SET(fd, &rd);
|
94
|
+
if( fd > max_fd ) { max_fd = fd; }
|
60
95
|
}
|
96
|
+
|
97
|
+
retval = select( max_fd+1, &rd, &wr, &er, &tv );
|
98
|
+
|
99
|
+
tv.tv_sec = 1;
|
100
|
+
tv.tv_usec = 0;
|
101
|
+
|
102
|
+
if( retval == 0 ) { printf("select timedout\n"); continue; }
|
103
|
+
if( retval == -1 && errno == EINTR ) { continue; }
|
104
|
+
if( retval < 0 ){ perror("select"); return false; }
|
105
|
+
|
106
|
+
bool finished_fd = false;
|
107
|
+
do {
|
108
|
+
finished_fd = false;
|
109
|
+
for( std::vector<int>::iterator i = set_fds.begin(); i != set_fds.end(); ++i ) {
|
110
|
+
int fd = *i;
|
111
|
+
|
112
|
+
if( FD_ISSET(fd,&rd) ) {
|
113
|
+
ResponseTable::iterator del_loc = response_table.find(fd);
|
114
|
+
ResponseDelegate *del = del_loc->second;
|
115
|
+
if( del ) {
|
116
|
+
retval = read(fd,READ_BUFFER,READ_SIZE);
|
117
|
+
if( retval >= 0 ) {
|
118
|
+
del->m_response->body.append(READ_BUFFER,retval);
|
119
|
+
if( retval == 0 ){
|
120
|
+
del->finish();
|
121
|
+
response_table.erase(del_loc);
|
122
|
+
set_fds.erase(i);
|
123
|
+
std::sort(set_fds.begin(),set_fds.end());
|
124
|
+
std::vector<int>::iterator max_loc = std::max(set_fds.begin(),set_fds.end());
|
125
|
+
max_fd = *max_loc;
|
126
|
+
FD_CLR(fd,&rd); // remove the file descriptor
|
127
|
+
printf("finished: %d of %d, max_fd: %d\n", ++finished_count, set_fds.size(), max_fd );
|
128
|
+
finished_fd = true;
|
129
|
+
delete del;
|
130
|
+
break;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
else {
|
134
|
+
perror("read");
|
135
|
+
return false;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}// end if
|
139
|
+
|
140
|
+
} // end for
|
141
|
+
|
142
|
+
}while( finished_fd );
|
143
|
+
}
|
144
|
+
|
145
|
+
return true;
|
146
|
+
}
|
147
|
+
|
148
|
+
ResponseDelegate::ResponseDelegate() :m_response(NULL)
|
149
|
+
{
|
150
|
+
}
|
151
|
+
|
152
|
+
ResponseDelegate::~ResponseDelegate()
|
153
|
+
{
|
154
|
+
close(m_pfd[0]);
|
155
|
+
delete m_response;
|
156
|
+
}
|
157
|
+
|
158
|
+
void ResponseDelegate::set_response( HttpResponse *ptr )
|
159
|
+
{
|
160
|
+
m_response = ptr;
|
161
|
+
}
|
162
|
+
|
163
|
+
bool ResponseDelegate::init()
|
164
|
+
{
|
165
|
+
if( pipe(m_pfd) ) { perror("pipe"); return false; }
|
166
|
+
return true;
|
167
|
+
}
|
168
|
+
|
169
|
+
void ResponseDelegate::finish()
|
170
|
+
{
|
171
|
+
printf("Response: %s, of %d bytes in %5lf seconds\n", m_response->name.c_str(), m_response->body.length(), m_response->response_time );
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
// catch SIGINT to kill process
|
176
|
+
static void SIGINT_handler(int sig)
|
177
|
+
{
|
178
|
+
exit(sig);
|
179
|
+
}
|
180
|
+
|
181
|
+
static bool make_request( const std::string &url, Dispatch &dispatcher, ResponseManager &rm )
|
182
|
+
{
|
183
|
+
ResponseDelegate *pres = new ResponseDelegate();
|
184
|
+
|
185
|
+
if( !pres->init() ){ delete pres; return false; }
|
186
|
+
|
187
|
+
// tell the request to stream the response over this file descriptor
|
188
|
+
//HttpRequest *req = new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/10/", pfd[1] );
|
189
|
+
HttpRequest *req = new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/10/", pres->m_pfd[1] );
|
190
|
+
//HttpResponse *res = req->m_response;
|
191
|
+
pres->set_response( req->m_response );
|
192
|
+
|
193
|
+
// make the request
|
194
|
+
dispatcher.request( req );
|
195
|
+
|
196
|
+
rm.watch_response( pres );
|
197
|
+
|
198
|
+
return true;
|
199
|
+
}
|
200
|
+
|
201
|
+
static void run_tests( Dispatch &dispatcher, int count )
|
202
|
+
{
|
203
|
+
time_t start_time = time(NULL);
|
204
|
+
int response_count = 0;
|
205
|
+
|
206
|
+
ResponseManager rm;
|
207
|
+
|
208
|
+
for( int i = 0; i < 50; ++i ) {
|
209
|
+
make_request( "http://127.0.0.1:4044/bytes/10/", dispatcher, rm );
|
61
210
|
}
|
62
|
-
|
63
|
-
|
64
|
-
delete res;
|
211
|
+
|
212
|
+
rm.process();
|
65
213
|
}
|
66
214
|
|
67
215
|
int main(int argc, char **argv)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#include "ev_dispatch.h"
|
2
|
+
#include "ev_http.h"
|
3
|
+
#include <sys/select.h>
|
4
|
+
#include <errno.h>
|
5
|
+
|
6
|
+
using namespace EVD;
|
7
|
+
|
8
|
+
|
9
|
+
// catch SIGINT to kill process
|
10
|
+
static void SIGINT_handler(int sig)
|
11
|
+
{
|
12
|
+
exit(sig);
|
13
|
+
}
|
14
|
+
|
15
|
+
static void run_tests( Dispatch &dispatcher, int count )
|
16
|
+
{
|
17
|
+
time_t start_time = time(NULL);
|
18
|
+
|
19
|
+
// tell the request to stream the response over this file descriptor
|
20
|
+
HttpRequest *req = new HttpRequest( dispatcher, "http://127.0.0.1:4044/test_post_length" );
|
21
|
+
req->set_opt("post", "hello there world");
|
22
|
+
|
23
|
+
request_t id = dispatcher.request( req );
|
24
|
+
|
25
|
+
struct timeval start;
|
26
|
+
Timer::current_time(&start);
|
27
|
+
|
28
|
+
while( dispatcher.wait_for_response_by_id( id, Timer(0,500*1000*1000) ) ) {
|
29
|
+
if( Timer::elapsed_time( &start ) > 2.0 ){
|
30
|
+
printf("exceeded max elasped time...\n");
|
31
|
+
break;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
HttpResponse *res = (HttpResponse *)dispatcher.response_for( id );
|
36
|
+
printf("response: %s, in %.5lf seconds of Content-Length: %d bytes\n%s%s\n", res->name.c_str(), res->response_time, res->body.length(), res->m_header.c_str(), res->body.c_str() );
|
37
|
+
delete res;
|
38
|
+
}
|
39
|
+
|
40
|
+
int main(int argc, char **argv)
|
41
|
+
{
|
42
|
+
Dispatch dispatcher;
|
43
|
+
|
44
|
+
if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
|
45
|
+
printf("SIGINT install error\n");
|
46
|
+
exit(1);
|
47
|
+
}
|
48
|
+
|
49
|
+
if( !dispatcher.start() ){
|
50
|
+
fprintf( stderr, "Failed to start up dispatcher\n" );
|
51
|
+
return 1;
|
52
|
+
}
|
53
|
+
|
54
|
+
//printf( "dispatcher thread running...\n" );
|
55
|
+
|
56
|
+
struct timeval start_time;
|
57
|
+
Timer::current_time(&start_time);
|
58
|
+
|
59
|
+
run_tests( dispatcher, 10 );
|
60
|
+
|
61
|
+
//printf( "total time: %.5f seconds\n", Timer::elapsed_time( &start_time ) );
|
62
|
+
|
63
|
+
dispatcher.stop();
|
64
|
+
|
65
|
+
return 0;
|
66
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#include "ev_dispatch.h"
|
2
|
+
#include "ev_http.h"
|
3
|
+
|
4
|
+
using namespace EVD;
|
5
|
+
|
6
|
+
|
7
|
+
// catch SIGINT to kill process
|
8
|
+
static void SIGINT_handler(int sig)
|
9
|
+
{
|
10
|
+
exit(sig);
|
11
|
+
}
|
12
|
+
|
13
|
+
static int run_test(Dispatch& dispatcher)
|
14
|
+
{
|
15
|
+
if( !dispatcher.start() ){
|
16
|
+
fprintf( stderr, "Failed to start up dispatcher\n" );
|
17
|
+
return 1;
|
18
|
+
}
|
19
|
+
|
20
|
+
printf( "dispatcher thread running...\n" );
|
21
|
+
std::vector<request_t> ids;
|
22
|
+
int TRIALS = 10;
|
23
|
+
|
24
|
+
for( int i = 0; i < TRIALS; ++i ) {
|
25
|
+
request_t id;
|
26
|
+
if( i % 2 ) {
|
27
|
+
id = dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/1000" ) );
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
id = dispatcher.request( new HttpRequest( dispatcher, "http://127.0.0.1:4044/bytes/10" ) );
|
31
|
+
}
|
32
|
+
ids.push_back( id );
|
33
|
+
}
|
34
|
+
Response *res;
|
35
|
+
for( int i = 0; i < ids.size(); ++i ) {
|
36
|
+
request_t id = ids[i];
|
37
|
+
while( dispatcher.wait_for_response_by_id( id, Timer(1,5) ) ){
|
38
|
+
printf("waiting for %d...\n", i);
|
39
|
+
}
|
40
|
+
res = dispatcher.response_for( id );
|
41
|
+
if( res ) {
|
42
|
+
printf("Recieved response from 2: %s, Content-Length: %d\n", res->name.c_str(), res->body.length() );
|
43
|
+
delete res;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
dispatcher.stop();
|
47
|
+
return 0;
|
48
|
+
}
|
49
|
+
|
50
|
+
int main(int argc, char **argv)
|
51
|
+
{
|
52
|
+
Dispatch dispatcher;
|
53
|
+
if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
|
54
|
+
printf("SIGINT install error\n");
|
55
|
+
return 1;
|
56
|
+
}
|
57
|
+
for( int i = 0; i < 10; ++i ) {
|
58
|
+
run_test(dispatcher);
|
59
|
+
}
|
60
|
+
|
61
|
+
return 0;
|
62
|
+
}
|