Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-17 Thread kdevel via Digitalmars-d-learn

On Friday, 17 November 2017 at 14:28:38 UTC, kdevel wrote:

On Thursday, 16 November 2017 at 19:37:31 UTC, ade90036 wrote:

Can we enable some sort of profiling to see what is going on?


You may compile the code with dmd -g -O -profile -profile=gc

I currently struggle getting meaningful output. I want to 
terminate the program after a number (say 400) handled 
requests. When returning from main the program hangs, so I call 
exit.


This works:

```
   if (++accept_cnt > 400) {
  writeln ("returning");
  taskPool.stop;
  return;
   }
```

I see the invocations [of the socket allocation wrapper] in 
handle_socket in

the console but not in trace.log.


Now they are in trace.log. Also I see this:

---
  Num  TreeFuncPer
  CallsTimeTimeCall
[...]
3991494852611824366   29635 void 
httpdtasks.handle_socket(std.socket.Socket)

---

30 milliseconds for handle_socket while the client side (Firefox) 
reports <= 1 ms. What does this mean?


There is another point that bothers me: In each handle_socket 
invocation a new SocketSet is created. How can this allocation be 
done once per thread (thread local storage)?


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-17 Thread kdevel via Digitalmars-d-learn

On Thursday, 16 November 2017 at 19:37:31 UTC, ade90036 wrote:

Can we enable some sort of profiling to see what is going on?


You may compile the code with dmd -g -O -profile -profile=gc

I currently struggle getting meaningful output. I want to 
terminate the program after a number (say 400) handled requests. 
When returning from main the program hangs, so I call exit.


The running binary now produces a trace.log but even after 
wrapping

new SocketSet(); into

```
auto socket_set_allocation_wrapper ()
{
   writeln (__FUNCTION__);
   return new SocketSet();
}
```

I see the invocations in handle_socket in the console but not in 
trace.log.





Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread Daniel Kozak via Digitalmars-d-learn
can you post both code, java and d, for sure we are all testing the sames

On Thu, Nov 16, 2017 at 8:37 PM, ade90036 via Digitalmars-d-learn <
digitalmars-d-learn@puremagic.com> wrote:

> So, what is next?
>
> Can we enable some sort of profiling to see what is going on?
>


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread ade90036 via Digitalmars-d-learn

So, what is next?

Can we enable some sort of profiling to see what is going on?


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread ade90036 via Digitalmars-d-learn


Mediocre result... let me create a java equivalent program so 
we have a direct comparison..


These are the tests for a similar program in java.

bombardier -c 200 -n 1 http://localhost:8081

Bombarding http://localhost:8081/ with 1 requests using 200 
connections
 1 / 1 
[==] 100.00% 0s

Done!
StatisticsAvg  StdevMax
  Reqs/sec 24527.29   14797.09  46439
  Latency8.25ms15.52ms   235.79ms
  HTTP codes:
1xx - 0, 2xx - 1, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
  Throughput: 3.87MB/s






Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread ade90036 via Digitalmars-d-learn

Result:

bombardier -c 200 -n 1 http://localhost:

Bombarding http://localhost: with 1 requests using 200 
connections
 1 / 1 
[===] 100.00% 1m24s

Done!
StatisticsAvg  StdevMax
  Reqs/sec   122.27 909.33  20363
  Latency   49.98ms   192.16ms  1.07s
  HTTP codes:
1xx - 0, 2xx - , 3xx - 0, 4xx - 0, 5xx - 0
others - 1
  Errors:
the server closed connection before returning the first 
response byte. Make sure the server returns 'Connection: close' 
response header before closing the connection - 1

  Throughput:36.89KB/s

Mediocre result... let me create a java equivalent program so we 
have a direct comparison..


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread ade90036 via Digitalmars-d-learn

On Thursday, 16 November 2017 at 18:44:11 UTC, Daniel Kozak wrote:
It works for me because I have multiple threads, but when I use 
only one
thread per pool (defaultPoolThreads(1)), it obviosly blocks, 
which is

correct behavior




Ok, let me force the: "defaultPoolThreads(8)" and let me re-test 
it.


By the way, if the socket is blocking you can remove all the 
socketSet and the socket.select as they are not needed anymore.


like this.. https://dpaste.dzfl.pl/ca09e4c54789







Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread Daniel Kozak via Digitalmars-d-learn
It works for me because I have multiple threads, but when I use only one
thread per pool (defaultPoolThreads(1)), it obviosly blocks, which is
correct behavior

On Thu, Nov 16, 2017 at 7:20 PM, Daniel Kozak  wrote:

> Hmm works ok for me. What OS?
>
> Dne 16. 11. 2017 12:05 dop. napsal uživatel "kdevel via
> Digitalmars-d-learn" :
>
> On Wednesday, 15 November 2017 at 13:31:46 UTC, Daniel Kozak wrote:
>>
>>> This one works ok for me, but I am on linux:
>>> https://dpaste.dzfl.pl/f54decee45bc
>>>
>>
>> It works, but it does not handle two connects in parallel. STR:
>>
>> 1. start the binary in console 1
>> 2. telnet localhost  in console 2
>> 3. telnet localhost  in console 3
>> 4. enter a [RETURN] in console (3)
>>
>> observed: nothing (the "thread" handling the first connect blocks)
>> expected: response
>>
>> On my machine defaultPoolThreads() returns 1. This can easily be
>> increased:
>>
>> ```
>>defaultPoolThreads(8);
>> ```
>>
>> There is also another problem with Socket.select: It may return -1. This
>> frequently happens when the ACCEPT socket is non-blocking and the select is
>> interrupted (by the GC?) then errno == EINTR.
>>
>> Also not having a timeout in the Socket.select of handle_socket allows
>> for DOS attacks like the one above. In case of a timeout select also
>> returns -1.
>>
>


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread ade90036 via Digitalmars-d-learn

On Thursday, 16 November 2017 at 18:20:36 UTC, Daniel Kozak wrote:

Hmm works ok for me. What OS?

Dne 16. 11. 2017 12:05 dop. napsal uživatel "kdevel via 
Digitalmars-d-learn" :



[...]


I'm running MacOS..


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread Daniel Kozak via Digitalmars-d-learn
Hmm works ok for me. What OS?

Dne 16. 11. 2017 12:05 dop. napsal uživatel "kdevel via
Digitalmars-d-learn" :

> On Wednesday, 15 November 2017 at 13:31:46 UTC, Daniel Kozak wrote:
>
>> This one works ok for me, but I am on linux:
>> https://dpaste.dzfl.pl/f54decee45bc
>>
>
> It works, but it does not handle two connects in parallel. STR:
>
> 1. start the binary in console 1
> 2. telnet localhost  in console 2
> 3. telnet localhost  in console 3
> 4. enter a [RETURN] in console (3)
>
> observed: nothing (the "thread" handling the first connect blocks)
> expected: response
>
> On my machine defaultPoolThreads() returns 1. This can easily be increased:
>
> ```
>defaultPoolThreads(8);
> ```
>
> There is also another problem with Socket.select: It may return -1. This
> frequently happens when the ACCEPT socket is non-blocking and the select is
> interrupted (by the GC?) then errno == EINTR.
>
> Also not having a timeout in the Socket.select of handle_socket allows for
> DOS attacks like the one above. In case of a timeout select also returns -1.
>


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-16 Thread ade90036 via Digitalmars-d-learn

On Wednesday, 15 November 2017 at 23:04:46 UTC, kdevel wrote:
On Wednesday, 15 November 2017 at 13:31:46 UTC, Daniel Kozak 
wrote:
This one works ok for me, but I am on linux: 
https://dpaste.dzfl.pl/f54decee45bc


It works, but it does not handle two connects in parallel. STR:

1. start the binary in console 1
2. telnet localhost  in console 2
3. telnet localhost  in console 3
4. enter a [RETURN] in console (3)

observed: nothing (the "thread" handling the first connect 
blocks)

expected: response

On my machine defaultPoolThreads() returns 1. This can easily 
be increased:


```
   defaultPoolThreads(8);
```

There is also another problem with Socket.select: It may return 
-1. This frequently happens when the ACCEPT socket is 
non-blocking and the select is interrupted (by the GC?) then 
errno == EINTR.


Also not having a timeout in the Socket.select of handle_socket 
allows for DOS attacks like the one above. In case of a timeout 
select also returns -1.


Hi Guys,

so i have tried the latest changes with destroy(socket) rather 
than socket.close().


Still the program is extremely slow.

I see that the httpclinet is making successfully 100 request at a 
time and then it freezes for 5/10 seconds and then it process 
another 100 request.


As Kdevel pointed out, this could be related to the Socket.select 
blocking on the interupt or it would be GC kicking in.


I also have seen the value computed for the defaultThread is not 
correct, hence i manually started the TaskPool(int thread) 
manually.


I'm going to share my benchmark program so you can guys test with 
the same tool.


Unfortunately it seems that there is some underline issue which 
is blocking the program and preventing to process all the 
incoming requests in a performant fashion, or at-least utilising 
the full CPU cycles.


reagrds

ade90036





Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread kdevel via Digitalmars-d-learn
On Wednesday, 15 November 2017 at 13:31:46 UTC, Daniel Kozak 
wrote:
This one works ok for me, but I am on linux: 
https://dpaste.dzfl.pl/f54decee45bc


It works, but it does not handle two connects in parallel. STR:

1. start the binary in console 1
2. telnet localhost  in console 2
3. telnet localhost  in console 3
4. enter a [RETURN] in console (3)

observed: nothing (the "thread" handling the first connect blocks)
expected: response

On my machine defaultPoolThreads() returns 1. This can easily be 
increased:


```
   defaultPoolThreads(8);
```

There is also another problem with Socket.select: It may return 
-1. This frequently happens when the ACCEPT socket is 
non-blocking and the select is interrupted (by the GC?) then 
errno == EINTR.


Also not having a timeout in the Socket.select of handle_socket 
allows for DOS attacks like the one above. In case of a timeout 
select also returns -1.


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread kdevel via Digitalmars-d-learn
On Wednesday, 15 November 2017 at 14:22:51 UTC, Daniel Kozak 
wrote:

And this one
https://paste.ofcode.org/KNqxcrmACLZLseB45MvwC


I thrash your code with two shell processes

```
while true; do curl 127.0.0.1: -o /dev/null; done
```

running parallel. Using strace -fFeclose on the binary this 
happens frequently:


```
:
[pid 10926] close(5)= 0
[pid 10926] close(4)= 0
[pid 10926] close(4)= 0
[pid 10926] close(4)= 0
[pid 10926] close(4)= 0
[pid 10926] --- SIGUSR1 (User defined signal 1) @ 0 (0) ---
[pid 10926] --- SIGUSR2 (User defined signal 2) @ 0 (0) ---
[pid 10919] close(4294967295)   = -1 EBADF (Bad file 
descriptor)
[pid 10919] close(4294967295)   = -1 EBADF (Bad file 
descriptor)
[pid 10919] close(4294967295)   = -1 EBADF (Bad file 
descriptor)

:
[pid 10919] close(4294967295)   = -1 EBADF (Bad file 
descriptor)
[pid 10919] close(4294967295)   = -1 EBADF (Bad file 
descriptor)
[pid 10919] close(4294967295)   = -1 EBADF (Bad file 
descriptor)

[pid 10926] close(4)= 0
[pid 10926] close(4)= 0
[pid 10926] close(4)= 0
:
```

The destructor of Socket is trying to close the already closed 
socket? If the worker I change


```
   socket.close();
```

to

```
destroy (socket);
```

these close(-1) calls go away.


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread Daniel Kozak via Digitalmars-d-learn
And this one
https://paste.ofcode.org/KNqxcrmACLZLseB45MvwC

Here you can test if threads makes difference
when compile with:
dmd -O -release -version=SINGLE_THREAD xxx.d
it will use only one thread
when compile with:
dmd -O -release xxx.d
it will use thread pool

On Wed, Nov 15, 2017 at 2:31 PM, Daniel Kozak  wrote:

> This one works ok for me, but I am on linux:
> https://dpaste.dzfl.pl/f54decee45bc
>
> On Wed, Nov 15, 2017 at 12:46 PM, Daniel Kozak  wrote:
>
>> Do not use your own taskPool, just use global taskPool proerty (import
>> std.parallelism: taskPool).
>>
>> You should not set blocking to false. And dont use Thread here.  There is
>> no reason to do that.  Just move that code into the main
>>
>> Dne 15. 11. 2017 12:15 odp. napsal uživatel "ade90036 via
>> Digitalmars-d-learn" :
>>
>> So thanks for the suggestions,  i have fixed HTTP response not postman
>> cal also parse the headers correctly!! happy days.
>>
>> I have removed the duration from the Socket.select but the application
>> seems to process a bunch or requests and then it stalls for several seconds
>> (3/5) and then it resumes.
>>
>> The httpclinet which i'm using to test the application is reporting:
>> "connection timeout".
>>
>> Could this be caused by the GC?
>>
>> ```updated code
>>
>> import std.algorithm : remove;
>> import std.conv : to;
>> import core.thread: Thread;
>> import std.socket : InternetAddress, Socket, SocketException, SocketSet,
>> TcpSocket, SocketShutdown;
>> import core.time : Duration, dur;
>> import std.stdio : writeln, writefln;
>> import std.parallelism : task, TaskPool;
>>
>> string to_retlf (string s)
>> {
>>import std.algorithm;
>>import std.string;
>>return s
>>   .lineSplitter
>>   .map!(a => chomp (a))
>>   .join ("\r\n");
>> }
>>
>> void main(string[] args)
>> {
>> ushort port;
>>
>> if (args.length >= 2)
>> port = to!ushort(args[1]);
>> else
>> port = ;
>>
>>
>> auto listener = new TcpSocket();
>> assert(listener.isAlive);
>> listener.blocking = false;
>> listener.bind(new InternetAddress(port));
>> listener.listen(100);
>> writefln("Listening on port %d.", port);
>>
>> auto taskPool = new TaskPool(8);
>>
>> string response = "HTTP/1.1 200 OK
>>
>> Server: dland:v2.076.1
>> Date: Tue, 11 Nov 2017 15:56:02 GMT
>> Content-Type: text/html; charset=UTF-8
>> Content-Length: 51
>>
>> Hello World!".to_retlf;
>>
>>
>> new Thread({
>> auto listeningSet = new SocketSet();
>> while(true) {
>> listeningSet.add(listener);
>> if (Socket.select(listeningSet, null, null)) {
>>
>> if (listeningSet.isSet(listener))// connection
>> request
>> {
>> Socket socket = listener.accept();
>> assert(socket.isAlive);
>>
>> //writefln("Connection from %s established.",
>> socket.remoteAddress().toString());
>> auto task = task!handle_socket(socket, response);
>> taskPool.put(task);
>> }
>> }
>> listeningSet.reset();
>> }
>> }).start();
>> }
>>
>>
>>
>> void handle_socket(Socket socket, string response) {
>>
>> auto socketSet = new SocketSet();
>> while(true) {
>> socketSet.add(socket);
>> if (Socket.select(socketSet, null, null)) {
>>
>> char[1024] buf;
>> auto datLength = socket.receive(buf[]);
>>
>> if (datLength == Socket.ERROR)
>> writeln("Connection error.");
>> else if (datLength != 0)
>> {
>> //writefln("Received %d bytes from %s: \"%s\"",
>> datLength, socket.remoteAddress().toString(), buf[0..datLength]);
>> //writefln("Writing response");
>> socket.send(response);
>>
>> }
>> // release socket resources now
>>
>> socket.close();
>>
>> break;
>>
>> }
>> socketSet.reset();
>> }
>> ```
>>
>> Regards
>>
>>
>>
>>
>>
>>
>>
>>
>>
>


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread Daniel Kozak via Digitalmars-d-learn
This one works ok for me, but I am on linux:
https://dpaste.dzfl.pl/f54decee45bc

On Wed, Nov 15, 2017 at 12:46 PM, Daniel Kozak  wrote:

> Do not use your own taskPool, just use global taskPool proerty (import
> std.parallelism: taskPool).
>
> You should not set blocking to false. And dont use Thread here.  There is
> no reason to do that.  Just move that code into the main
>
> Dne 15. 11. 2017 12:15 odp. napsal uživatel "ade90036 via
> Digitalmars-d-learn" :
>
> So thanks for the suggestions,  i have fixed HTTP response not postman cal
> also parse the headers correctly!! happy days.
>
> I have removed the duration from the Socket.select but the application
> seems to process a bunch or requests and then it stalls for several seconds
> (3/5) and then it resumes.
>
> The httpclinet which i'm using to test the application is reporting:
> "connection timeout".
>
> Could this be caused by the GC?
>
> ```updated code
>
> import std.algorithm : remove;
> import std.conv : to;
> import core.thread: Thread;
> import std.socket : InternetAddress, Socket, SocketException, SocketSet,
> TcpSocket, SocketShutdown;
> import core.time : Duration, dur;
> import std.stdio : writeln, writefln;
> import std.parallelism : task, TaskPool;
>
> string to_retlf (string s)
> {
>import std.algorithm;
>import std.string;
>return s
>   .lineSplitter
>   .map!(a => chomp (a))
>   .join ("\r\n");
> }
>
> void main(string[] args)
> {
> ushort port;
>
> if (args.length >= 2)
> port = to!ushort(args[1]);
> else
> port = ;
>
>
> auto listener = new TcpSocket();
> assert(listener.isAlive);
> listener.blocking = false;
> listener.bind(new InternetAddress(port));
> listener.listen(100);
> writefln("Listening on port %d.", port);
>
> auto taskPool = new TaskPool(8);
>
> string response = "HTTP/1.1 200 OK
>
> Server: dland:v2.076.1
> Date: Tue, 11 Nov 2017 15:56:02 GMT
> Content-Type: text/html; charset=UTF-8
> Content-Length: 51
>
> Hello World!".to_retlf;
>
>
> new Thread({
> auto listeningSet = new SocketSet();
> while(true) {
> listeningSet.add(listener);
> if (Socket.select(listeningSet, null, null)) {
>
> if (listeningSet.isSet(listener))// connection
> request
> {
> Socket socket = listener.accept();
> assert(socket.isAlive);
>
> //writefln("Connection from %s established.",
> socket.remoteAddress().toString());
> auto task = task!handle_socket(socket, response);
> taskPool.put(task);
> }
> }
> listeningSet.reset();
> }
> }).start();
> }
>
>
>
> void handle_socket(Socket socket, string response) {
>
> auto socketSet = new SocketSet();
> while(true) {
> socketSet.add(socket);
> if (Socket.select(socketSet, null, null)) {
>
> char[1024] buf;
> auto datLength = socket.receive(buf[]);
>
> if (datLength == Socket.ERROR)
> writeln("Connection error.");
> else if (datLength != 0)
> {
> //writefln("Received %d bytes from %s: \"%s\"", datLength,
> socket.remoteAddress().toString(), buf[0..datLength]);
> //writefln("Writing response");
> socket.send(response);
>
> }
> // release socket resources now
>
> socket.close();
>
> break;
>
> }
> socketSet.reset();
> }
> ```
>
> Regards
>
>
>
>
>
>
>
>
>


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread Daniel Kozak via Digitalmars-d-learn
Do not use your own taskPool, just use global taskPool proerty (import
std.parallelism: taskPool).

You should not set blocking to false. And dont use Thread here.  There is
no reason to do that.  Just move that code into the main

Dne 15. 11. 2017 12:15 odp. napsal uživatel "ade90036 via
Digitalmars-d-learn" :

So thanks for the suggestions,  i have fixed HTTP response not postman cal
also parse the headers correctly!! happy days.

I have removed the duration from the Socket.select but the application
seems to process a bunch or requests and then it stalls for several seconds
(3/5) and then it resumes.

The httpclinet which i'm using to test the application is reporting:
"connection timeout".

Could this be caused by the GC?

```updated code

import std.algorithm : remove;
import std.conv : to;
import core.thread: Thread;
import std.socket : InternetAddress, Socket, SocketException, SocketSet,
TcpSocket, SocketShutdown;
import core.time : Duration, dur;
import std.stdio : writeln, writefln;
import std.parallelism : task, TaskPool;

string to_retlf (string s)
{
   import std.algorithm;
   import std.string;
   return s
  .lineSplitter
  .map!(a => chomp (a))
  .join ("\r\n");
}

void main(string[] args)
{
ushort port;

if (args.length >= 2)
port = to!ushort(args[1]);
else
port = ;


auto listener = new TcpSocket();
assert(listener.isAlive);
listener.blocking = false;
listener.bind(new InternetAddress(port));
listener.listen(100);
writefln("Listening on port %d.", port);

auto taskPool = new TaskPool(8);

string response = "HTTP/1.1 200 OK

Server: dland:v2.076.1
Date: Tue, 11 Nov 2017 15:56:02 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 51

Hello World!".to_retlf;


new Thread({
auto listeningSet = new SocketSet();
while(true) {
listeningSet.add(listener);
if (Socket.select(listeningSet, null, null)) {

if (listeningSet.isSet(listener))// connection
request
{
Socket socket = listener.accept();
assert(socket.isAlive);

//writefln("Connection from %s established.",
socket.remoteAddress().toString());
auto task = task!handle_socket(socket, response);
taskPool.put(task);
}
}
listeningSet.reset();
}
}).start();
}



void handle_socket(Socket socket, string response) {

auto socketSet = new SocketSet();
while(true) {
socketSet.add(socket);
if (Socket.select(socketSet, null, null)) {

char[1024] buf;
auto datLength = socket.receive(buf[]);

if (datLength == Socket.ERROR)
writeln("Connection error.");
else if (datLength != 0)
{
//writefln("Received %d bytes from %s: \"%s\"", datLength,
socket.remoteAddress().toString(), buf[0..datLength]);
//writefln("Writing response");
socket.send(response);

}
// release socket resources now

socket.close();

break;

}
socketSet.reset();
}
```

Regards


Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread ade90036 via Digitalmars-d-learn
So thanks for the suggestions,  i have fixed HTTP response not 
postman cal also parse the headers correctly!! happy days.


I have removed the duration from the Socket.select but the 
application seems to process a bunch or requests and then it 
stalls for several seconds (3/5) and then it resumes.


The httpclinet which i'm using to test the application is 
reporting: "connection timeout".


Could this be caused by the GC?

```updated code
import std.algorithm : remove;
import std.conv : to;
import core.thread: Thread;
import std.socket : InternetAddress, Socket, SocketException, 
SocketSet, TcpSocket, SocketShutdown;

import core.time : Duration, dur;
import std.stdio : writeln, writefln;
import std.parallelism : task, TaskPool;

string to_retlf (string s)
{
   import std.algorithm;
   import std.string;
   return s
  .lineSplitter
  .map!(a => chomp (a))
  .join ("\r\n");
}

void main(string[] args)
{
ushort port;

if (args.length >= 2)
port = to!ushort(args[1]);
else
port = ;

auto listener = new TcpSocket();
assert(listener.isAlive);
listener.blocking = false;
listener.bind(new InternetAddress(port));
listener.listen(100);
writefln("Listening on port %d.", port);

auto taskPool = new TaskPool(8);

string response = "HTTP/1.1 200 OK
Server: dland:v2.076.1
Date: Tue, 11 Nov 2017 15:56:02 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 51

Hello World!".to_retlf;

new Thread({
auto listeningSet = new SocketSet();
while(true) {
listeningSet.add(listener);
if (Socket.select(listeningSet, null, null)) {
if (listeningSet.isSet(listener))// 
connection request

{
Socket socket = listener.accept();
assert(socket.isAlive);
//writefln("Connection from %s established.", 
socket.remoteAddress().toString());
auto task = task!handle_socket(socket, 
response);

taskPool.put(task);
}
}
listeningSet.reset();
}
}).start();
}



void handle_socket(Socket socket, string response) {
auto socketSet = new SocketSet();
while(true) {
socketSet.add(socket);
if (Socket.select(socketSet, null, null)) {
char[1024] buf;
auto datLength = socket.receive(buf[]);

if (datLength == Socket.ERROR)
writeln("Connection error.");
else if (datLength != 0)
{
//writefln("Received %d bytes from %s: \"%s\"", 
datLength, socket.remoteAddress().toString(), buf[0..datLength]);

//writefln("Writing response");
socket.send(response);
}
// release socket resources now

socket.close();

break;

}
socketSet.reset();
}
```

Regards









Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-15 Thread ade90036 via Digitalmars-d-learn

On Tuesday, 14 November 2017 at 21:09:40 UTC, kdevel wrote:

On Tuesday, 14 November 2017 at 19:57:54 UTC, ade90036 wrote:


while(true) {
listeningSet.add(listener);
if (Socket.select(listeningSet, null, null, 
dur!"nsecs"(150)) > 0) {


Why do you ever timeout? This loop consumes 100 % (a single 
core) when idle on my machine.


Thanks for you feedback, i'll make those cosmetic changes to the 
HTTP response


Why do i specify a timeout in the Socket.select?

I have noticed that if i don't specify a timeout the 
Socket.select seems to block every so often for several seconds 
(2/5sec) and i have read in another post to specify a timeout 
value to the call.


I'll retest now.




Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-14 Thread kdevel via Digitalmars-d-learn

On Tuesday, 14 November 2017 at 19:57:54 UTC, ade90036 wrote:


while(true) {
listeningSet.add(listener);
if (Socket.select(listeningSet, null, null, 
dur!"nsecs"(150)) > 0) {


Why do you ever timeout? This loop consumes 100 % (a single core) 
when idle on my machine.





Re: NIO+Multithreaded TCPSocket listener, very low cpu utilisation

2017-11-14 Thread kdevel via Digitalmars-d-learn

On Tuesday, 14 November 2017 at 19:57:54 UTC, ade90036 wrote:

socket.send("HTTP/1.1 200 OK
   Server: 
dland:v2.076.1
   Date: Tue, 11 
Nov 2017 15:56:02 GMT
   Content-Type: 
text/plain; charset=UTF-8
   Content-Length: 
32


   
Hello World!");

}


Some cosmetic changes: It is possible, that your HTTP client gets 
confused by the data sent?


```
socket.send("HTTP/1.1 200 OK
Server: dland:v2.076.1
Date: Tue, 11 Nov 2017 15:56:02 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 51

Hello World!".to_retlf);

string to_retlf (string s)
{
   import std.algorithm;
   import std.string;
   return s
  .lineSplitter
  .map!(a => chomp (a))
  .join ("\r\n");
}
```

The Content-Length given is too short. The Content-Type also was 
wrong.