From 1b6bbc619dcaf5f97a2a18f29adf2e0146222640 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 15 Jul 2009 17:00:15 +0200 Subject: [PATCH] Bugfix: Server-side clients not attached between creation and on_connect. Solution is to manually add Attach() to OnConnection. For client side it seems there is no Detach() being called after NS resolution? Otherwise I would have removed it. That was another bug. Note: We don't want to modify evnet's behavior to have on_connect called directly when the socket is accepted. evnet needs to support SSL, and on_connect is supposed to signal that the SSL connection is established. The point here is that being "connected" and being "attached" to the event loop are two different things. SSL stuff may be transmitted when a socket is not "connected" but it must always be attached. --- src/net.cc | 2 + src/net.h | 1 - test/mjsunit/test-tcp-many-clients.js | 69 +++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 test/mjsunit/test-tcp-many-clients.js diff --git a/src/net.cc b/src/net.cc index fb50950d92..5fad7a0456 100644 --- a/src/net.cc +++ b/src/net.cc @@ -549,6 +549,8 @@ Server::OnConnection (struct sockaddr *addr) Emit("connection", 1, argv); + connection->Attach(); + return connection; } diff --git a/src/net.h b/src/net.h index 5992febf5a..47f6967c65 100644 --- a/src/net.h +++ b/src/net.h @@ -68,7 +68,6 @@ private: /* liboi callbacks */ static void on_connect (evnet_socket *s) { Connection *connection = static_cast (s->data); - connection->Attach(); connection->OnConnect(); } diff --git a/test/mjsunit/test-tcp-many-clients.js b/test/mjsunit/test-tcp-many-clients.js new file mode 100644 index 0000000000..8c70cab241 --- /dev/null +++ b/test/mjsunit/test-tcp-many-clients.js @@ -0,0 +1,69 @@ +include("mjsunit.js"); +// settings +var port = 20743; +var bytes = 1024*40; +var concurrency = 100; +var connections_per_client = 5; + +// measured +var total_connections = 0; + +var body = ""; +for (var i = 0; i < bytes; i++) { + body += "C"; +} + +var server = node.tcp.createServer(function (c) { + c.addListener("connect", function () { + total_connections++; + print("#"); + c.send(body); + c.fullClose(); + }); +}); +server.listen(port); + +function runClient (callback) { + var client = node.tcp.createConnection(port); + client.connections = 0; + client.setEncoding("utf8"); + + client.addListener("connect", function () { + client.recved = ""; + client.connections += 1; + }); + + client.addListener("receive", function (chunk) { + this.recved += chunk; + }); + + client.addListener("eof", function (had_error) { + client.close(); + }); + + client.addListener("disconnect", function (had_error) { + print("."); + assertFalse(had_error); + assertEquals(bytes, client.recved.length); + if (this.connections < connections_per_client) { + this.connect(port); + } else { + callback(); + } + }); +} + + +function onLoad () { + var finished_clients = 0; + for (var i = 0; i < concurrency; i++) { + runClient(function () { + if (++finished_clients == concurrency) server.close(); + }); + } +} + +function onExit () { + assertEquals(connections_per_client * concurrency, total_connections); + puts("\nokay!"); +}