-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Any plans on building reactive client? #317
Comments
I don't have plans for that. I think there is some talk of doing an API revisit for all the clients, so perhaps during that. Perhaps Richard has some insight. |
@agcom @jameshilliard @gytis-ivaskevicius a few questions about this, since it is a substantial undertaking:
If it is the later option, what is the use-case, since typically you just have a single NatsConnection in your JVM, and thus moving to nio would not likely create a big performance improvement. |
@brimworks a reactive client is easier to use; an end-to-end reactive client is easier to use and more efficient. Is the efficiency of an end-to-end reactive client considerable? My blind opinion: in extreme conditions yes; e.g. a short-lived app, running on a mobile device, a military software, a developer with OCD, and an over-engineer. If it's gonna be a refactor, just a reactive interface is sufficient; at some point, throughout optimizing internal codes, there is nothing to do other than making tasks lazy by chaining them to their reactive listeners. If there is gonna be a big-bang, there shouldn't be any reason against making it end-to-end from the beginning. |
@agcom So my take is that you believe strongly in reactive architecture and that's fine, but it's hard to see your comments as anything other than opinion. But that's okay, you can address that easily. Why specifically is a reactive client easier to use and why is it more efficient, for what use cases do you mean? How would these use cases apply to the common developer where traffic is not high? Where it is high? Very distributed? Not at all distributed? How will being reactive improve applications where the problem isn't the number of transactions, but where the information is located, i.e. on the edge? Is it more secure or do you have to do additional work to be secure? Is it faster or slower, or is that even the point? What are the trade offs of using a reactive pattern? These are an example of things I'd like to see in analysis so we can determine if, given our limited resources, undertaking this development is a good idea. |
@scottf I'm not the right guy to do such a survey on. Below says why I think non-blocking is more efficient. I always strive for perfection; and believe that going non-blocking is the way, but of-course it might not be economically efficient. In terms of efficiency, non-blocking architecture uses less resources, because it spawns fewer OS threads, and memory allocations & using CPU cycles happen on demand; e.g. binary to text to object conversation happens when someone is waiting for it. It's faster because benchmarks do say so; e.g. consider Apache Tomcat vs Netty (Vertex, Reactor Netty). Currently in Java, writing non-blocking code is harder because you can't write synchronous style non-blocking code, in contrast with Kotlinx coroutines and Golang; Project Loom is to rescue in the future. |
@scottf @brimworks And hey, I don't think making a fully non-blocking client is a substantial undertake. I wrote a simple (publish & sub) fully non-blocking Nats client on top of Kotlinx coroutines and NIO2 (async NIO) in 1 day, most of the time was reading Nats docs. Ignore my comment if I'm being naive. |
So, I'm still trying to wrap my mind around how this would be implemented @agcom. Specifically, there is the JDK Flow API, and then there is RXJava, AkkaStreams, and ProjectReactor which allow interop with JDK Flow API. Is the idea here that a NATS connection would implement the JDK Flow API. Specifically, the Flow.Publisher API for publishing messages and Flow.Subscriber for subscriptions? If so, then using blocking I/O with a reader and writer thread would just be an "implementation detail"... and I haven't seen any use-cases where anyone is trying to scale up the number of instances of a NATS connection, and thus I don't see any benefit in implementing on top of a non-blocking socket. Is someone on this thread willing to sketch out an API for this so there is something more concrete to work off of? |
@brimworks JDK Flow, RXJava, AkkaStreams, and ProjectReactor, all allow interop with each other directly or indirectly through JDK Flow or org.reactivestreams (org.reactivestreams suggest migrating to JDK Flow). It would be wise to use only JDK Flow API in ABI (application binary interface, e.g. Yes, deep down it can use a blocking TCP client with two threads (reader & writer), which is completely fine. But, I mean, using a non-blocking TCP client isn't that hard; specially if it's a rich TCP client, e.g. Reactor Netty. I guess the only difficulty of using one is handling buffers (e.g. pooling, concatenating), in contrast to having a byte stream.
Me neither, but it isn't impossible to do so. |
Actually, one other benefit of going full end-to-end reactive is avoiding the need for the OS to context-switch threads when doing basic PING/PONG type of operations. For example, if doing a health check by subscribing to an _INBOX, and then PUBlishing a message to this _INBOX requires context switching from the health check thread, over to the writer thread, then to the reader thread to read the response, then to the dispatcher thread handling the _INBOX subscription, and then finally to the health check thread. I've seen some really bad round-trip times in this scenario, although I have not put a profiler on it yet. However, I have a hunch that doing 4 thread context switches is probably adding a lot of unnecessary latency when running in the context of a high load on a single CPU VM, since many other processes may be ran between these context switches. |
+1 |
Just like the title says - I was wondering if you guys are planning on building a reactive version of this client using
ProjectReactor
The text was updated successfully, but these errors were encountered: