kwik
kwik copied to clipboard
NIO2 Asynchronous channel or something simillar support?
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?
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.
Ok, first of all we must explain a few concepts:
- NIO - API introduced in java 1.4, using
Selectorsto handle multiple connections on one thread. When one or more connections are ready, selector returningSelection 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,
completedandfailed). when data was received, thencompletedfuction is executed (withByteBufferparameter). 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 runcompletedmethod 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 |
|---|---|