kwik icon indicating copy to clipboard operation
kwik copied to clipboard

NIO2 Asynchronous channel or something simillar support?

Open rafi612 opened this issue 2 years ago • 2 comments

Hi, I want to make server using kwik, but I cant find information about any support for "async" data processing. Something like calling "read" method with lambda argument, and executing lambda when result is done on thread from thread pool. This give performance impact (We don't need to run thread for single connection, instead threads are reused and called when it is necessary). When I use TCP before, I've done this using Java NIO api. Is there something simillar in kwik?

rafi612 avatar Sep 15 '23 12:09 rafi612

No, there isn't. I've been thinking about supporting another read/write interface apart from the input/output streams that is there now, and there are certainly several ways to add it. But there is a ton of things that can or should be added and my time is limited. But if you want to help, we could discuss how such an addition should look like and how it should hook in into the existing code.

ptrd avatar Sep 16 '23 07:09 ptrd

Ok, first of all we must explain a few concepts:

  • NIO - API introduced in java 1.4, using Selectors to handle multiple connections on one thread. When one or more connections are ready, selector returning Selection Keys (one key for every action from all connections e.g read, write, accept). Then we can handle it.
  • NIO2 - API introduced in java 1.7, unlike NIO it process every connection on multiple threads from thread pool. When we call e.g read function, we passed anonymous class to it (2 methods, completed and failed). when data was received, then completed fuction is executed (with ByteBuffer parameter). The important thing is that read function not creating new thread to wait connection, but use specific kernel call (e.g epoll on linux) under the mask, to handle read and run completed method when result is ready.

In java TCP has implemented both NIO and NIO2. UDP has implemented only NIO,I think because of its construction (it's conectionless).

How we can implement this in kwik?

I assume that kwik use blocking datagram sockets from java.net package. To implement NIO2 in kwik properly, it must use NIO API for UDP sockets, and then delegate it to NIO2 interface using thread pool that can be use by end user. This is a very simplified speculation and I probably didn't think something through. I don't know if some changes would be necessary in agent15 too. I know that it may be difficult to add, but I think it is worth it.

Why it everything?

Because of performance. Here some screenshots of my TCP server, tested with "benchmark" (1000 clients gradually connecting and and sending packets).

Blocking TCP Sockets NIO2 TCP Sockets
obraz obraz

rafi612 avatar Sep 16 '23 20:09 rafi612