MongoDB extension : reactive and imperative : to split or not to split

159 views
Skip to first unread message

Loïc MATHIEU

unread,
Apr 19, 2021, 8:48:13 AM4/19/21
to Quarkus Development mailing list
Hello,

Currently, there is 4 MongoDB related extensions:
- mongodb-client: the client, with a Mutiny based reactive wrapper (on top of the MongoDB reactive stream client)
- mongodb-panache
- mongodb-panache-kotlin
- rest-data-panache-mongodb

All these extensions support imperative (based on the mongodb sync client) and reactive style programming (based on the wrapper).

If we look at other extensions, they usually ship the imperative and the reactive variant in separate extensions, this avoids having too many dependencies inside an application, in the case of reasyeasy (and Hibernate also I think), you cannot use both on the same application.

So, may we split the MongoDB extensions in two ?

If we do this, we can do it two ways:
1. The existing extensions will be for the imperative client, new extensions will be created for the reactive. This would mandate someone that uses the reactive variant to include the new dependency (we can maybe check the usage of the reactive client via Jandex and throw an exception with a clear message).
2. Create two new sets of extensions, and refactor the existing one to include both. This will not break things for existing users but will inflate the number of existing extensions. And when we later on remove the legacy extension we will break users.

As most users certainly use the imperative variant, I think 1. is safe if we decided to split.

WDYT ?

clement escoffier

unread,
Apr 19, 2021, 10:08:04 AM4/19/21
to Loïc MATHIEU, Quarkus Development mailing list
Hello,

What's the rationale behind the split? Hibernate and Resteasy did the split because the internals, in both cases, is very different. But here, it's the same fundamental layer (the reactive streams driver being based on the regular one)?

Clement

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJLxjVH-AUFGf7aMjChEr4pK_1g3RveAJj2j1C1AKA%2B%3DsJN2Gg%40mail.gmail.com.

Stephane Epardaud

unread,
Apr 19, 2021, 10:10:54 AM4/19/21
to Loïc MATHIEU, Quarkus Development mailing list
You didn't say why you want to split them? Just for consistency with the other extensions?

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJLxjVH-AUFGf7aMjChEr4pK_1g3RveAJj2j1C1AKA%2B%3DsJN2Gg%40mail.gmail.com.


--
Stéphane Épardaud

Loïc MATHIEU

unread,
Apr 19, 2021, 10:25:32 AM4/19/21
to Stephane Epardaud, clement escoffier, Quarkus Development mailing list
Why: consistency, less dependency at runtime as the sync and the reactive stream drivers are now separated (which was not the case when the mongodb client extension was created two years ago). This will also mean smaller extensions (but more of them).

It's open for discussion, I know we already discussed this without doing any more to avoid breaking stuff, I just want to discuss it again in case we decided to do it for Quarkus 2.

@clement escoffier the mongodb reactive stream client is not based on the sync client, the split has been made some time ago (after you first created the Mongodb client extension). They do share some common libraries (mongodb-client-core and bson) so I'm not sure if it will make a huge difference for the imperative client, I can try to make an estimate.

Stephane Epardaud

unread,
Apr 19, 2021, 10:54:28 AM4/19/21
to Loïc MATHIEU, clement escoffier, Quarkus Development mailing list
In general, I would agree with you, I guess. But if we look at it from the "If It Ain't Broke Don't Fix It" perspective, how many users have complained?
--
Stéphane Épardaud

clement escoffier

unread,
Apr 19, 2021, 12:05:29 PM4/19/21
to Stephane Epardaud, Loïc MATHIEU, Quarkus Development mailing list
Le lun. 19 avr. 2021 à 16:54, Stephane Epardaud <stephane...@gmail.com> a écrit :
In general, I would agree with you, I guess. But if we look at it from the "If It Ain't Broke Don't Fix It" perspective, how many users have complained?

On Mon, 19 Apr 2021 at 16:25, Loïc MATHIEU <loik...@gmail.com> wrote:
Why: consistency, less dependency at runtime as the sync and the reactive stream drivers are now separated (which was not the case when the mongodb client extension was created two years ago). This will also mean smaller extensions (but more of them).

It's open for discussion, I know we already discussed this without doing any more to avoid breaking stuff, I just want to discuss it again in case we decided to do it for Quarkus 2.

@clement escoffier the mongodb reactive stream client is not based on the sync client, the split has been made some time ago (after you first created the Mongodb client extension). They do share some common libraries (mongodb-client-core and bson) so I'm not sure if it will make a huge difference for the imperative client, I can try to make an estimate.

That's not totally correct. To have spent hours digging in their last version of the client last week, I can assure you that it's all based on the "driver-core" API, especially com.mongodb.internal.async.AsyncBatchCursor.  Basically, the sync and reactive streams APIs are just slim facades on top of their driver-core API. Both facades do not contain much code. 

Clement

Loïc MATHIEU

unread,
Apr 19, 2021, 12:22:41 PM4/19/21
to clement escoffier, Stephane Epardaud, Quarkus Development mailing list
OK, so the real differences will be to not include mutiny, reactive stream operators, context-propagation and others ...

It will lower the API surface so using it will be more straightforward.

This will also fix some bugs, at least one : today in MongoDB with Panache we create both imperative and reactive clients even if we didn't need both. This can be fixed in another way.

clement escoffier

unread,
Apr 19, 2021, 1:27:23 PM4/19/21
to Loïc MATHIEU, Stephane Epardaud, Quarkus Development mailing list
Le lun. 19 avr. 2021 à 18:22, Loïc MATHIEU <loik...@gmail.com> a écrit :
OK, so the real differences will be to not include mutiny, reactive stream operators, context-propagation and others ...

In 2.x, we won't have reactive streams operators anymore. You should only have mutiny (which is basically always there) and context-propagation (which also is often around). 

It will lower the API surface so using it will be more straightforward.

This will also fix some bugs, at least one : today in MongoDB with Panache we create both imperative and reactive clients even if we didn't need both. This can be fixed in another way.

Can't we detect which one is used? 

Just to be clear, I'm not against a split, IF we can avoid the "I used synchronous mongo with my resteasy reactive endpoint" (I'm not sure we detect that yet). Note also that I'm a _bit_ unhappy with the latest driver (which explains why I spent hours digging last week). 

Loïc MATHIEU

unread,
Apr 20, 2021, 3:37:07 AM4/20/21
to clement escoffier, Stephane Epardaud, Quarkus Development mailing list
> Can't we detect which one is used?

Yes, sure, it's on my todo list for some month now :) if we didn't split I'll work on it.

>  IF we can avoid the "I used synchronous mongo with my resteasy reactive endpoint" (I'm not sure we detect that yet)

We don't detect this already for MongoDB with Panache, it's an interesting point because it'll be possible ONLY if we split. If we want to always enforce (via incompatible extensions or WARNING during the build phase) to use reactive DB clients with RESTEasy (or any other combinaison of reactive libs) we need to implement this check in the build steps of all extensions.
As I understand it, it's always better to be fully reactive when possible, I already found some issues while auditing some misbehaving application due to a mix of synchronous and reactive code. 
So if we want to help people not to shoot them in the foot, we may implement as many checks as we can to advise using reactive counterparts when existing.

Justin Lee

unread,
Apr 20, 2021, 10:59:01 AM4/20/21
to Loïc MATHIEU, clement escoffier, Stephane Epardaud, Quarkus Development mailing list
So, some thoughts.  On the redundant initialization of the imperative and reactive mongo clients, can we not lazy initialize those?  Then the unused one, if there is one unused, would never get initialized.

As far as splitting the modules goes, i would make the splits around imperative vs reactive.  I would move the kotlin code in to the java module and make the kotlin dep optional.  This would let users simply depend on, say, mongodb-panache and if they wanted to use kotlin, they'd simply depend on kotlin itself (maybe quarkus-kotlin depending).  But this would give them one module to worry about and it would simply both the project layout and the build to combine those modules.  I'd have to do some digging but it could possibly mean even removing a 'common' module or two as there would be no need for a third module to share code between the java and kotlin modules.  It can be done fairly simply and non-invasively for those who'd rather not load up kotlin in their IDEs even.  But overall would be *much* simpler to manage.

Loïc MATHIEU

unread,
Apr 20, 2021, 11:09:45 AM4/20/21
to evanc...@redhat.com, clement escoffier, Stephane Epardaud, Quarkus Development mailing list
I didn't think about Kotlin, but if we can merge the Java and Kotlin extensions for MongoDB with Panache, Hibernate with Panache and REST data with Panache this would be very cool and will ease the maintenance a lot !

Loïc MATHIEU

unread,
Apr 29, 2021, 3:38:45 AM4/29/21
to evanc...@redhat.com, clement escoffier, Stephane Epardaud, Quarkus Development mailing list
Hi,

If we want to make the split, we only have a few weeks (2 I think) before 2.0 will be branched so we need to make the decision soon.

So, the advantage of the split will be :
- Less API surface for the user
- The ability to enforce (or at least warn) using the reactive version when using RESTEasy reactive
- Align with what REASTEasy and Hibernate does, even if they did it because they must do it whereas for MongoDB both can cohabit (even if it is not a good idea to use both)

So disadvantage :
- Don't break something that ain't broker
- Twice the library count
- Needless split as MongoDB share much of the libraries for the two drivers and the extension can live as it

The main advantage I can see is if we want to enforce (or at least advise via a WARNING) to use the reactive driver if RESTEasy reactive (or reactive route) is used, if we plan to do this in a near future we need the split.

So guys ? Final thoughts ?

clement escoffier

unread,
Apr 29, 2021, 8:26:20 AM4/29/21
to Loïc MATHIEU, evanc...@redhat.com, Stephane Epardaud, Quarkus Development mailing list
+1 for a split.

Clement

Stephane Epardaud

unread,
Apr 30, 2021, 5:32:27 AM4/30/21
to clement escoffier, Loïc MATHIEU, evanc...@redhat.com, Quarkus Development mailing list
OK, fine.
--
Stéphane Épardaud
Reply all
Reply to author
Forward
0 new messages