[JAVA-774] Add support for asynchronous operations Created: 28/Feb/13  Updated: 31/May/16  Resolved: 31/Mar/15

Status: Closed
Project: Java Driver
Component/s: Async
Affects Version/s: None
Fix Version/s: 3.0.0

Type: Epic Priority: Major - P3
Reporter: Ben McCann Assignee: Unassigned
Resolution: Done Votes: 10
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related

 Description   

It would be great to have the Java driver be non-blocking. As far as I know it's currently only possible to make non-blocking requests if I use the Scala ReactiveMongo driver



 Comments   
Comment by Jeffrey Yemin [ 24/Mar/14 ]

One other point I should have made in my last comment: Both the AIO and the Netty support are just implementations of the https://github.com/mongodb/mongo-java-driver/blob/3.0.x/driver/src/main/org/mongodb/connection/Stream.java#L29 interface defined by the driver, and so it would be fairly straightforward to create another implementation on top of a different library (e.g. Unix domain sockets) and plug it in to your application.

Comment by Remon van Vliet [ 24/Mar/14 ]

I'd say point 2) hints at the most important advantage. AIO is a very low-level API and Netty includes various solutions to non-trivial problems that would otherwise would have to be implemented in the MongoDB driver from scratch. Add to that that Netty is probably the most widely used and thus most proven library for this sort of thing (as opposed to MINA, Grizzly, etc.) it's a low risk dependency.

Comment by Jeffrey Yemin [ 21/Mar/14 ]

Hi Nils,

Thanks for your interest in async.

We are still leveraging AIO and have no plans currently to remove AsynchronousSocketChannelStream. This is the default implementation that the driver uses for async.
Furthermore, there is not a hard dependency on Netty. It's opt-in (via a system property, though that may change), and if you don't opt-in, Netty does not need to be on the classpath.

But Netty gives us some advantages.

1. AsynchronousSocketChannel was introduced in Java 7, and we would like a solution for our Java 6 users. Netty is supported on Java 6 and up.
2. Our AsynchronousSocketChannel-based implementation does not support SSL, and adding that support is non-trivial. With Netty, it's just a few lines of code.
3. For applications that already use Netty for the rest of their I/O needs, a Netty-based driver for MongoDB may integrate better. For example, they could share an instance of an NioEventLoopGroup.

That said, if you have specific objections to any reliance on Netty we would definitely like to hear them.

Regards,
Jeff

Comment by Nils [ 21/Mar/14 ]

What was the reason to add the Netty dependency rather than leverage Java AIO?

Comment by Jeffrey Yemin [ 21/Mar/14 ]

For anyone interested, I have a working branch of 3.0.x that works with Netty 4.0: https://github.com/jyemin/mongo-java-driver/tree/3.0.x-netty.

Feedback is appreciated.

Comment by Nils [ 24/Jul/13 ]

Well, maybe 2, one for reads the other for writes. It's been a while since I've done non-blocking I/O using selectors, and it was only for one-way traffic, so I'm a little rusty.

Comment by Remon van Vliet [ 24/Jul/13 ]

Nils, so a thread per connection strategy? Provided the amount of connections is relatively limited that should be okay.

Comment by Nils [ 24/Jul/13 ]

EDIT: What I'm trying to say is, that I would expect each connection to have a single selector, thus be single-threaded. And you should then be able to control the connection pool size, so that each connection == single thread == single selector.

Sorry for any confusion.

Comment by Nils [ 24/Jul/13 ]

Remon, I think this comes down to whether you value latency or throughput.

I certainly hope there will be an option to limit both physical I/O connections and the number of selector threads.

Comment by Remon van Vliet [ 24/Jul/13 ]

Nils, there's a number of reasons why that isn't optimal (or even possible). A single thread would mean only a single physical core can process MongoDB traffic, only a single operation can execute concurrently and so I don't think that's an option. In a non-blocking framework the multiple threads wouldn't be really be contending for the same I/O resources anyway as each worker thread would be assigned it's own I/O resource (connection) to perform an A/C/R/W on.

Generally speaking a single thread implementation (server and client) rarely reach maximum throughput. It's roughly for that reason why things like node.js and Redis require multiple instances on the same physical machine to maximimze throughput. That said, there is value in having as few threads as possible. If the entire driver is mostly non-blocking this max should be roughly the amount of physical/virtual processing units.

A single connection introduces some of the same limitations.

Comment by Remon van Vliet [ 24/Jul/13 ]

Justin, sounds like a good plan

Comment by Justin Lee [ 24/Jul/13 ]

Remon, we're hoping/planning to remove that dependency.

Comment by Nils [ 24/Jul/13 ]

Jeff, you mention that "we also need a non-blocking connection pool", but why is that? Why not use a single connection and single thread? Since it's async this should work very well, probably even better than multiple thread contending over I/O resources, and it's more efficient for the server too.

Comment by Remon van Vliet [ 24/Jul/13 ]

Out of pure curiousity, what's the rationale behind making 3.x drivers Java 7+? NIO is only a slightly more verbose/low-level API than ASC is and Java 7 adaption isn't exactly great still.

Comment by Jeffrey Yemin [ 21/May/13 ]

Fall 2013. You can track in on the Jira roadmap.

Comment by Nils [ 21/May/13 ]

Jeff, asynchronoussocketchannel sounds like a good choice. Is there an approximate ETA on the 3.0 driver?

Comment by Ben McCann [ 21/May/13 ]

Right, I know. Totally worth it though

Comment by Jeffrey Yemin [ 21/May/13 ]

You'll have the same problem with MongoJack though, as it also will need an async API makeover.

Comment by Ben McCann [ 21/May/13 ]

No problem. I'm happy to port as needed. I gave up on using Morphia anyway. It was way too buggy and unmaintained and had a horrible memory leak that causing us lots of headaches. I'm much happier using MongoJack now.

Comment by Jeffrey Yemin [ 21/May/13 ]

Oops, I had already mentioned that!

Comment by Jeffrey Yemin [ 21/May/13 ]

Ben, there's no way that the existing Morphia API will become asynchronous without a bit of work, but we will likely have a way that you'll be able to use your existing @Entity-annotated classes directly with the driver's async API.

Comment by Ben McCann [ 21/May/13 ]

+1 for AsynchronousSocketChannel. sounds like absolutely the right way to go

Comment by Jeffrey Yemin [ 21/May/13 ]

Nils, our current prototype of this feature uses AsynchronousSocketChannel (and hence depends on Java 7). That is most likely going to remain, though we haven't made a final decision.

Also, it's a bit more complicated than that, because we also need a non-blocking connection pool.

Comment by Nils [ 21/May/13 ]

I am going to assume, and want to make sure, that the non-blocking behavior will be implemented using NIO selectors, correct?

Comment by Ben McCann [ 28/Feb/13 ]

Ok, sounds good. I don't have any problem switching my annotations to use the javax.persistence annotations or something else if needed. It's a very easy search and replace. One there's some sort of serializer for Java objects (doesn't have to be Morphia), I'd be happy to test it out.

Comment by Jeffrey Yemin [ 28/Feb/13 ]

Morphia is not going to be rolled in, but we are going to write a Morphia serializer that will allow you to use classes with Morphia annotations directly with the new API, including the async API. But that piece is not done yet.

Comment by Ben McCann [ 28/Feb/13 ]

Btw, if there's some ORM functionality built-in (e.g. Morphia rolled in) then I'd be happy to plop it into my app and test it. Otherwise it might be pretty tough for me to test in my existing app since I don't use the driver directly.

Comment by Ben McCann [ 28/Feb/13 ]

Awesome! I'm super excited for the v3 driver now!

Comment by Jeffrey Yemin [ 28/Feb/13 ]

I agree, and we're working on it. If you'd like to test out what we have so far, please let me know.

Generated at Thu Feb 08 08:53:02 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.