--
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/CAD%2BL2cy0OXvaGDhj4Lf8LfvtQwvQ-ff2Aq9bT5EqQB3UU_erWg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CALeTM-kf_E%3D3bKxEycDzgZNMGYfon367%3Dkz8HWsDcE12T3nU%3DQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJ97idGgtS-TkE-GHnqd9-cYdyX0N4p5N0VyAGOKNA2sSHSZYw%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJLxjVFVqDtyshncEAvxXeDw2uJf1iBRYM3FOB4VpYL244ssvQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJ97idHXJFJNMz-VM2zqoicvWxCTcjrouCcU1N%2B88xteb15roQ%40mail.gmail.com.
The problem is not with users who know what they are doing. The problem is that most users have absolutely no idea what reactive means (and don't care about learning about it, they just want to keep doing what they are doing). If going reactive didn't have any trade-off, we could just keep our position and say "just learn this new thing" but that's not the case.
My guess is that in a reasonable future, we will want to make RESTEasy Reactive our default REST stack. IIRC, I advocated for blocking as default exactly for this reason back in the time: people used to reactive know what they are doing and can tweak things, people not aware of reactive can just use it without any hassle (and more than that, they are not even aware reactive exists and the constraints it comes with).
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJ97idE-e51VVyEzq89SwbxLZhd4SD-JkgwJPVDWw5aHQdRz6A%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAO8YPTQjVrSY%2Bo8nRc%3DaKb_ssfbPNodOnM1zvozUf11AVQRp%2Bg%40mail.gmail.com.
My guess is that in a reasonable future, we will want to make RESTEasy Reactive our default REST stack. IIRC, I advocated for blocking as default exactly for this reason back in the time: people used to reactive know what they are doing and can tweak things, people not aware of reactive can just use it without any hassle (and more than that, they are not even aware reactive exists and the constraints it comes with).
I originally was in the camp to make the default blocking. However, as I was saying in a chat with Stuart, I am a convert! The existing approach is awesome, and the usability impact is much smaller than I originally expected it would be (caveats to come).
First, though let’s talk about future.
I’d like to see us get off of the resteasy classic as the default ASAP (perhaps 2.1 or 2.2) and go all in on restesy-reactive. However, it’s been pointed out that the name causes confusion because resteasy-reactive isnt JUST reactive. It offers big gains for blocking as well. So to address that I propose we rename the extension to “quarkus-rest”. The library we use under the hood is still resteasy-reactive, but we talk about it as Quarkus Rest, and explain that Quarkus Rest is super fast REST for both scenarios, and it’s built on resteasy-reactive + vert.x. We would keep some kind of alias to avoid breaking people. We would then switch all our docs and guides and defaults to Quarkus REST, and formally deprecate the resteasy (“classic”) extension.
Back to the main topic, I actually like the explicit declaration of Blocking. It makes the user actually think about, and understand, the I/O model they are using, and by doing so they avoid hidden performance problems. The small cost they pay is we force explicit declaration with a runtime validation error. Unlike the hidden surprises though, this feedback is effectively immediate and tells you what you need to fix. As also mentioned in the thread we could make this error message even more helpful.
Just to clarify on the hidden performance problems, what I mean is that a user does something truly stateless (simple redirection, static content of some form, computation, send a message. etc), or they try to use reactive to speed up some processing, it looks like it works, but then after deploying, they notice a bottleneck. Granted the fix is simple but the cost to find it is much higher than the immediate error scenario we are able to do with accidental usage of blocking. So defaulting to the easier-to-detect setting makes sense to me. It also helps us when folks throw together a benchmark out of the box and make the wrong assumptions on how we compare to other modern reactive-defaulting stacks. Not that apple vs orange benchmarks should drive our decisions!
I like the idea of doing smart things if someone picks hibernate traditional, although my suggestion would be to generate @Blocking on the methods (or maybe the resource class), and not a separate @Application class, which is off hidden somewhere . Also ideally we would generate a full working hibernate basic scenario with update or drop-and-create table creation options specified. That way the user is good to go.
In the future when we have Loom, we could probably look at just making the default be “coroutine”.
Worst case scenario is everyone hates it and we need to look at changing it.
Thoughts?
-Jason
On Jun 25, 2021 at 2:44:27 AM, Guillaume Smet <guillau...@gmail.com> wroteMy guess is that in a reasonable future, we will want to make RESTEasy Reactive our default REST stack. IIRC, I advocated for blocking as default exactly for this reason back in the time: people used to reactive know what they are doing and can tweak things, people not aware of reactive can just use it without any hassle (and more than that, they are not even aware reactive exists and the constraints it comes with).I originally was in the camp to make the default blocking. However, as I was saying in a chat with Stuart, I am a convert! The existing approach is awesome, and the usability impact is much smaller than I originally expected it would be (caveats to come).
First, though let’s talk about future.
I’d like to see us get off of the resteasy classic as the default ASAP (perhaps 2.1 or 2.2) and go all in on restesy-reactive. However, it’s been pointed out that the name causes confusion because resteasy-reactive isnt JUST reactive. It offers big gains for blocking as well. So to address that I propose we rename the extension to “quarkus-rest”. The library we use under the hood is still resteasy-reactive, but we talk about it as Quarkus Rest, and explain that Quarkus Rest is super fast REST for both scenarios, and it’s built on resteasy-reactive + vert.x. We would keep some kind of alias to avoid breaking people. We would then switch all our docs and guides and defaults to Quarkus REST, and formally deprecate the resteasy (“classic”) extension.
Back to the main topic, I actually like the explicit declaration of Blocking. It makes the user actually think about, and understand, the I/O model they are using, and by doing so they avoid hidden performance problems. The small cost they pay is we force explicit declaration with a runtime validation error. Unlike the hidden surprises though, this feedback is effectively immediate and tells you what you need to fix. As also mentioned in the thread we could make this error message even more helpful.
Just to clarify on the hidden performance problems, what I mean is that a user does something truly stateless (simple redirection, static content of some form, computation, send a message. etc), or they try to use reactive to speed up some processing, it looks like it works, but then after deploying, they notice a bottleneck. Granted the fix is simple but the cost to find it is much higher than the immediate error scenario we are able to do with accidental usage of blocking. So defaulting to the easier-to-detect setting makes sense to me. It also helps us when folks throw together a benchmark out of the box and make the wrong assumptions on how we compare to other modern reactive-defaulting stacks. Not that apple vs orange benchmarks should drive our decisions!
I like the idea of doing smart things if someone picks hibernate traditional, although my suggestion would be to generate @Blocking on the methods (or maybe the resource class), and not a separate @Application class, which is off hidden somewhere .
Also ideally we would generate a full working hibernate basic scenario with update or drop-and-create table creation options specified. That way the user is good to go.
In the future when we have Loom, we could probably look at just making the default be “coroutine”.
Worst case scenario is everyone hates it and we need to look at changing it.
Thoughts?
-Jason
--
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/CAJMo4%2BeAhH2V9UeknAJNi50Qf8o-Lz%3DBHN9N96P8zNr0kccG%3Dw%40mail.gmail.com.
Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.
Also I still don't see how any of this can play well with @Transactional
On Jun 25, 2021, at 11:56 AM, Jason Greene <jason....@redhat.com> wrote:
Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Right but AFAICT all of this is detected because we don’t do it based on API, we just wait till the first blocking operation gets ran, which will eventually happen since the db will block. Is there a scenario you are thinking of that I am missing?
On Jun 25, 2021, at 11:56 AM, Jason Greene <jason....@redhat.com> wrote:Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Right but AFAICT all of this is detected because we don’t do it based on API, we just wait till the first blocking operation gets ran, which will eventually happen since the db will block. Is there a scenario you are thinking of that I am missing?More specially what I mean is that before the http response returns and the method call completes one of two things will happen: a) the user made some blocking call which we immediately report as an error (method throws exception) or b) nothing blocked and everything ran on the event loop fine.
On Fri, 25 Jun 2021 at 18:11, Jason Greene <jason....@redhat.com> wrote:On Jun 25, 2021, at 11:56 AM, Jason Greene <jason....@redhat.com> wrote:Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Right but AFAICT all of this is detected because we don’t do it based on API, we just wait till the first blocking operation gets ran, which will eventually happen since the db will block. Is there a scenario you are thinking of that I am missing?More specially what I mean is that before the http response returns and the method call completes one of two things will happen: a) the user made some blocking call which we immediately report as an error (method throws exception) or b) nothing blocked and everything ran on the event loop fine.Ok I had misunderstood your proposal then; you said "my suggestion would be to generate @Blocking on the methods " which made me wonder how you can define the boundary of such methods, to decide where exactly the annotation needs to be added.
What you say now seems more like what Paul also suggested? +1 for Paul's idea.
Let's just remember that some calls might elude detection even though they are blocking if they happen to succeed quickly enough; this implies that "observing" only the first call won't be good enough - not if we need full certainty at least.
--
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/cd2b9783-0007-40ab-9c16-4d4a242f4f0cn%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJMo4%2BdkGAmrxsrqa2Ljb8BSXb1aZpRjJAGxKsH5Uf_RcCBVrA%40mail.gmail.com.
Quandry for me: this introduces friction for anyone bringing code over from some other existing app, and somewhat violates the principle of least surprise: they used the code they were accustomed to, and behavior changed (their code failed with an exception, and they have to add an annotation to make it behave as they expect).I remember that the discussions about this last time went on for awhile.. but for signatures that match old / existing / “classic” signatures, I feel like the safest/least-surprising choice should be blocking. Using an async or reactive return type (Uni/Multi/*Future/something) would automatically trigger async behavior..
Now this is obviously counter to what we want (which is more folks getting the benefit of non-blocking/async behavior).So if we indeed want to do that (and make resteasy reactive the default stack), we need to make the experience less “surprising” in the negative sense… Their code should just work, to the greatest extent we can manage, which could mean compensating when they do something that we know is a blocking activity in an async context. We know enough to throw the exception… if we can do something nicer, we should.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJwjk9x4r-zOqNDMM-fVit7t3uCHPOc7zaOw9X3EH9FprAsDzQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CALeTM-nrFmY9xVs%3D%2Bv19RGdVbYoBeGR8Z5jyq-hQSvHef8%2BXNw%40mail.gmail.com.
My performance tests show that if we consider RR on eventloop to be the ultimate, and compare plain resteasy and RR with @Blocking they stack up as follows in terms of end to end latency of a simple hello world rest service using wrk as the load test tool on localhost:
RR on eventloop: 23 microseconds
RR with @Blocking: 31 microseconds
Normal resteasy extension: 48 microsecondsNormal resteasy and undertow extensions: 52 microseconds
So the question I ask myself is this - would a developer who does not know or care about eventloops and blocking and reactive and worker pools, care about 8 microseconds? Someone who does care about those 8 microseconds would know to use @NonBlocking on their endpoint which is so latency sensitive. Light only travels 2.4km in 8 microseconds - people who care about that are not running codestarts with default settings on their production environments... I'm all for "make it work out the box" and then if you want to run a TechEmpower competition or build a real time trading platform then you know you have some tweeks you can do but with the caution and knowledge of an experienced developer.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAO8YPTRT_a%2BtH4ESyJMUm-kaAmmcb5Zg5iv0yH_CXp__%2BG3fSw%40mail.gmail.com.
I like how we do it now. Maybe the error message could be improved further but we fail fast. It will fail in a test, or in manual testing in dev mode if someone starts doing blocking things.I like it more than the adaptive approach. It is straightforward, users know what is happening, no hidden surprises.But I agree with Stuart that blocking by default is much easier for new users.And it's better to change it sooner rather than later.
I like simple, for me if we are to switch to blocking by default, a property (in application.properties) to override it would be best.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAO8YPTR2513RBctxYwcW6Ek53Jy-hvoLbnMoW%2BcE5ahkpUz8Pw%40mail.gmail.com.
Now this is obviously counter to what we want (which is more folks getting the benefit of non-blocking/async behavior).
--
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/7158ff83-4188-4fa1-a3bb-594c93ed19d7n%40googlegroups.com.
I know it would be complex to implement but the best option IMHO is to instead of throwing an exception when blocking on an event loop thread, rather flag the rest resource method as blocking, log a warning and from that point on in the lifetime of the process, pretend the developer added @Blocking annotation on the method.
This would mean that:a) Any example or combination of extensions would always "work" OOTBb) If you don't block or do anything special, you get the best performance possiblec) If you end up blocking an event loop, it won't happen again on that methodPerhaps there could be a config setting for resteasy reactive for eventloop blocking policy - something like:- fail: do what it does currently- warn: log a warning and continue and don't adapt to blocking for subsequent calls- auto: log a warning and adapt to blocking for subsequent callsThen I would make it auto by default and encourage using fail for more experienced developers in sensitive production environments which should never block an event loop.
On Fri, Jun 25, 2021 at 9:59 AM Alexey Loubyansky <alexey.l...@redhat.com> wrote:
On Fri, Jun 25, 2021 at 9:45 AM Guillaume Smet <guillau...@gmail.com> wrote:
The problem is not with users who know what they are doing. The problem is that most users have absolutely no idea what reactive means (and don't care about learning about it, they just want to keep doing what they are doing). If going reactive didn't have any trade-off, we could just keep our position and say "just learn this new thing" but that's not the case.If users select a reactive extension and don't know what reactive means, and don't care about learning what that means, I'd say it's their problem. IMO, the exception we are throwing in case of JPA/JDBC is of great help (even to those who know what they are doing but simply missed the @Blocking in the code).
My guess is that in a reasonable future, we will want to make RESTEasy Reactive our default REST stack. IIRC, I advocated for blocking as default exactly for this reason back in the time: people used to reactive know what they are doing and can tweak things, people not aware of reactive can just use it without any hassle (and more than that, they are not even aware reactive exists and the constraints it comes with).
If we do change to the resteasy-reactive as the default JAX-RS extension that'll change the situation. Currently, it's an explicit user's choice.
I suppose taking into account the extensions could be an acceptable trade-off, even if not perfect (given some extensions expose both paradigms as mentioned by Loïc). In that case, I would go the blocking route by default and go with the comment Martin asked for.
On Fri, Jun 25, 2021 at 9:31 AM Loïc MATHIEU <loik...@gmail.com> wrote:
It's more complex than that, what will you do when a user includes the MongoDB extension which supports both blocking and reactive ?What if a user includes Hibernate ORM and some other reactive extension, and always dispatches to a worker thread (via a subscribeOn() method) because he knows what he's doing ?
Le ven. 25 juin 2021 à 09:04, Alexey Loubyansky <alexey.l...@redhat.com> a écrit :
A possible argument against changing the default could be that the resteasy-reactive isn't the default JAX-RS extension. To have it in the app it (or one of the reactive extensions that depend on it) has to be added to the project by the user. "Reactive" is in its name, which should raise awareness.
On Fri, Jun 25, 2021 at 8:16 AM Georgios Andrianakis <gand...@redhat.com> wrote:
Thanks for bringing it up Stuart,I personally think 3 is the best solution, but 2 would also be nice.Avoiding 1 should be our goal I think because not only would it be surprising for existing users, but it would also make it more difficult that solution 2 to get the full power of the Reactive behavior
On Fri, Jun 25, 2021, 09:11 Stuart Douglas <sdou...@redhat.com> wrote:
--Hi Everyone,I would like to revisit the topic of the default blocking vs non-blocking for RESTEasy Reactive. As we start to push users more towards RESTEasy Reactive I think the non-blocking by default behaviour is problematic for new users. For example if I generate an application with RESTEasy Reactive an Panache, and then attempt to use a panache entity in the endpoint I end up with:"java.lang.IllegalStateException: You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking EntityManager operations make sure you are doing it from a worker thread."Now we could improve this error message to try and detect what has happened and tell the user to use @Blocking, however it's still not a great user experience where the most basic of CRUD endpoints fails out of the box.I am not really sure what the best solution is here, but I think we have a few options:1) Change the default to @Blocking, but in a smart way so we can still dispatch to @Async endpoints without switching to a worker threadI think it is more likely that a reactive programmer will understand the difference between worker and IO threads, so it makes more sense to make the reactive programmer have to change the default, while someone just getting started may not have a clue why they need @Blocking or what the difference is.2) Always include an Application class with @Blocking in the generated codestart3) Include an Application class with @Blocking in the generated codestart if any blocking extensions are selectedE.g. if you include Hibernate ORM you will end up with an app configured for blocking by default, if you only include reactive extensions you won't.I don't super like either of these options, but in terms of making the getting started experience easy maybe we should change the default? I think leaving things as they are will potentially be a barrier to new users if we start to push RESTEasy Reactive more.What do people think?Stuart
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/CAD%2BL2cy0OXvaGDhj4Lf8LfvtQwvQ-ff2Aq9bT5EqQB3UU_erWg%40mail.gmail.com.
--
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/CALeTM-kf_E%3D3bKxEycDzgZNMGYfon367%3Dkz8HWsDcE12T3nU%3DQ%40mail.gmail.com.
--
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/CAJ97idGgtS-TkE-GHnqd9-cYdyX0N4p5N0VyAGOKNA2sSHSZYw%40mail.gmail.com.
--
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/CAJLxjVFVqDtyshncEAvxXeDw2uJf1iBRYM3FOB4VpYL244ssvQ%40mail.gmail.com.
--
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/CAJ97idE-e51VVyEzq89SwbxLZhd4SD-JkgwJPVDWw5aHQdRz6A%40mail.gmail.com.
On Fri, 25 Jun 2021, 17:31 Jason Greene, <jason....@redhat.com> wrote:
On Jun 25, 2021 at 2:44:27 AM, Guillaume Smet <guillau...@gmail.com> wroteMy guess is that in a reasonable future, we will want to make RESTEasy Reactive our default REST stack. IIRC, I advocated for blocking as default exactly for this reason back in the time: people used to reactive know what they are doing and can tweak things, people not aware of reactive can just use it without any hassle (and more than that, they are not even aware reactive exists and the constraints it comes with).I originally was in the camp to make the default blocking. However, as I was saying in a chat with Stuart, I am a convert! The existing approach is awesome, and the usability impact is much smaller than I originally expected it would be (caveats to come).
First, though let’s talk about future.
I’d like to see us get off of the resteasy classic as the default ASAP (perhaps 2.1 or 2.2) and go all in on restesy-reactive. However, it’s been pointed out that the name causes confusion because resteasy-reactive isnt JUST reactive. It offers big gains for blocking as well. So to address that I propose we rename the extension to “quarkus-rest”. The library we use under the hood is still resteasy-reactive, but we talk about it as Quarkus Rest, and explain that Quarkus Rest is super fast REST for both scenarios, and it’s built on resteasy-reactive + vert.x. We would keep some kind of alias to avoid breaking people. We would then switch all our docs and guides and defaults to Quarkus REST, and formally deprecate the resteasy (“classic”) extension.
Back to the main topic, I actually like the explicit declaration of Blocking. It makes the user actually think about, and understand, the I/O model they are using, and by doing so they avoid hidden performance problems. The small cost they pay is we force explicit declaration with a runtime validation error. Unlike the hidden surprises though, this feedback is effectively immediate and tells you what you need to fix. As also mentioned in the thread we could make this error message even more helpful.
Just to clarify on the hidden performance problems, what I mean is that a user does something truly stateless (simple redirection, static content of some form, computation, send a message. etc), or they try to use reactive to speed up some processing, it looks like it works, but then after deploying, they notice a bottleneck. Granted the fix is simple but the cost to find it is much higher than the immediate error scenario we are able to do with accidental usage of blocking. So defaulting to the easier-to-detect setting makes sense to me. It also helps us when folks throw together a benchmark out of the box and make the wrong assumptions on how we compare to other modern reactive-defaulting stacks. Not that apple vs orange benchmarks should drive our decisions!
I like the idea of doing smart things if someone picks hibernate traditional, although my suggestion would be to generate @Blocking on the methods (or maybe the resource class), and not a separate @Application class, which is off hidden somewhere .
Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Also I still don't see how any of this can play well with @Transactional.
On Fri, 25 Jun 2021 at 18:11, Jason Greene <jason....@redhat.com> wrote:On Jun 25, 2021, at 11:56 AM, Jason Greene <jason....@redhat.com> wrote:Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Right but AFAICT all of this is detected because we don’t do it based on API, we just wait till the first blocking operation gets ran, which will eventually happen since the db will block. Is there a scenario you are thinking of that I am missing?More specially what I mean is that before the http response returns and the method call completes one of two things will happen: a) the user made some blocking call which we immediately report as an error (method throws exception) or b) nothing blocked and everything ran on the event loop fine.Ok I had misunderstood your proposal then; you said "my suggestion would be to generate @Blocking on the methods " which made me wonder how you can define the boundary of such methods, to decide where exactly the annotation needs to be added.What you say now seems more like what Paul also suggested? +1 for Paul's idea.Let's just remember that some calls might elude detection even though they are blocking if they happen to succeed quickly enough; this implies that "observing" only the first call won't be good enough - not if we need full certainty at least.
So the question I ask myself is this - would a developer who does not know or care about eventloops and blocking and reactive and worker pools, care about 8 microseconds?
StuartThanksSince our user are using our live coding facilities they see this right away, and say we make the error better “Did you forget to say @Blocking on your resource class or method?”
--
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/CAD%2BL2czo_wHrTB-s89xP6_mDX0%3Dv3uiiH_jpByDNaRr34oeZig%40mail.gmail.com.
On Mon, 28 Jun 2021 at 03:22, Stuart Douglas <sdou...@redhat.com> wrote:On Sat, 26 Jun 2021 at 04:06, Sanne Grinovero <sa...@hibernate.org> wrote:On Fri, 25 Jun 2021 at 18:11, Jason Greene <jason....@redhat.com> wrote:On Jun 25, 2021, at 11:56 AM, Jason Greene <jason....@redhat.com> wrote:Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Right but AFAICT all of this is detected because we don’t do it based on API, we just wait till the first blocking operation gets ran, which will eventually happen since the db will block. Is there a scenario you are thinking of that I am missing?More specially what I mean is that before the http response returns and the method call completes one of two things will happen: a) the user made some blocking call which we immediately report as an error (method throws exception) or b) nothing blocked and everything ran on the event loop fine.Ok I had misunderstood your proposal then; you said "my suggestion would be to generate @Blocking on the methods " which made me wonder how you can define the boundary of such methods, to decide where exactly the annotation needs to be added.What you say now seems more like what Paul also suggested? +1 for Paul's idea.Let's just remember that some calls might elude detection even though they are blocking if they happen to succeed quickly enough; this implies that "observing" only the first call won't be good enough - not if we need full certainty at least.In most cases we have detection that looks at the current thread, rather than relying on anything time based. We actually need this to implement blocking on top of NIO to avoid deadlocks, if you block the IO thread in one of our InputStream implementations you would deadlock as the IO Thread is the thread that delivers the data and unblocks the waiting thread.Right, for example if someone invokes a method on Hibernate Reactive on a non-vertx thread we move the operation to a vertx context - by checking the thread type. I guess that's a good start - are you suggesting we should have such checks more pervasively across all frameworks?For example I suppose we could patch Hibernate ORM (blocking) to do the opposite: check that it's not running on a vertx thread, and if it does to trigger some [warning|exception].But I doubt it's going to be practical to gap all holes in all libraries, especially if we have to include registered callbacks and pluggable extension points? I guess we could cover a great deal of them but I wouldn't assume we can create a water tight net to catch all situations, and it would be a bit weird to have users come to rely on such a mechanism if in practice we can't catch them all. So back to my point: sure we can do this but let's set the right expectations, as in we can't detect all cases. It will certainly require a combination of looking at thread types and checking the vertx-is-stuck flags.Besides, there's many practical tricks people do use on ORM blocking which will make some of its usage non-blocking; it would be very annoying for the "classic" users to start spewing out exceptions or warnings for perfectly acceptable cases. For example on many projects I've worked on, there would be a fair amount of entities identified which are extremely hot in the read path of the application, and people would use various techniques to ensure 100% cache hit ratios.To do this, you'd most likely have a bootstrap method filling in such caches, or just warmup the application by hitting the same endpoints as you'd normally receive traffic on: during this warmup phase it would be "acceptable" to block exceptionally, as it's never going to block when under production load even though it might block once on first call.So if you want to go this path, please ensure people can turn it off if they want to.
On Fri, Jun 25, 2021 at 9:45 AM Guillaume Smet <guillau...@gmail.com> wrote:The problem is not with users who know what they are doing. The problem is that most users have absolutely no idea what reactive means (and don't care about learning about it, they just want to keep doing what they are doing). If going reactive didn't have any trade-off, we could just keep our position and say "just learn this new thing" but that's not the case.If users select a reactive extension and don't know what reactive means, and don't care about learning what that means, I'd say it's their problem. IMO, the exception we are throwing in case of JPA/JDBC is of great help (even to those who know what they are doing but simply missed the @Blocking in the code).
On Mon, 28 Jun 2021 at 19:21, Sanne Grinovero <sa...@hibernate.org> wrote:On Mon, 28 Jun 2021 at 03:22, Stuart Douglas <sdou...@redhat.com> wrote:On Sat, 26 Jun 2021 at 04:06, Sanne Grinovero <sa...@hibernate.org> wrote:On Fri, 25 Jun 2021 at 18:11, Jason Greene <jason....@redhat.com> wrote:On Jun 25, 2021, at 11:56 AM, Jason Greene <jason....@redhat.com> wrote:Remember lazy loading of entities and their attributes is a key aspect of programming with JPA.If you have JPA in the application, we won't be able to easily identify which calls to which APIs are blocking as potentially any user's code could block.Right but AFAICT all of this is detected because we don’t do it based on API, we just wait till the first blocking operation gets ran, which will eventually happen since the db will block. Is there a scenario you are thinking of that I am missing?More specially what I mean is that before the http response returns and the method call completes one of two things will happen: a) the user made some blocking call which we immediately report as an error (method throws exception) or b) nothing blocked and everything ran on the event loop fine.Ok I had misunderstood your proposal then; you said "my suggestion would be to generate @Blocking on the methods " which made me wonder how you can define the boundary of such methods, to decide where exactly the annotation needs to be added.What you say now seems more like what Paul also suggested? +1 for Paul's idea.Let's just remember that some calls might elude detection even though they are blocking if they happen to succeed quickly enough; this implies that "observing" only the first call won't be good enough - not if we need full certainty at least.In most cases we have detection that looks at the current thread, rather than relying on anything time based. We actually need this to implement blocking on top of NIO to avoid deadlocks, if you block the IO thread in one of our InputStream implementations you would deadlock as the IO Thread is the thread that delivers the data and unblocks the waiting thread.Right, for example if someone invokes a method on Hibernate Reactive on a non-vertx thread we move the operation to a vertx context - by checking the thread type. I guess that's a good start - are you suggesting we should have such checks more pervasively across all frameworks?For example I suppose we could patch Hibernate ORM (blocking) to do the opposite: check that it's not running on a vertx thread, and if it does to trigger some [warning|exception].But I doubt it's going to be practical to gap all holes in all libraries, especially if we have to include registered callbacks and pluggable extension points? I guess we could cover a great deal of them but I wouldn't assume we can create a water tight net to catch all situations, and it would be a bit weird to have users come to rely on such a mechanism if in practice we can't catch them all. So back to my point: sure we can do this but let's set the right expectations, as in we can't detect all cases. It will certainly require a combination of looking at thread types and checking the vertx-is-stuck flags.Besides, there's many practical tricks people do use on ORM blocking which will make some of its usage non-blocking; it would be very annoying for the "classic" users to start spewing out exceptions or warnings for perfectly acceptable cases. For example on many projects I've worked on, there would be a fair amount of entities identified which are extremely hot in the read path of the application, and people would use various techniques to ensure 100% cache hit ratios.To do this, you'd most likely have a bootstrap method filling in such caches, or just warmup the application by hitting the same endpoints as you'd normally receive traffic on: during this warmup phase it would be "acceptable" to block exceptionally, as it's never going to block when under production load even though it might block once on first call.So if you want to go this path, please ensure people can turn it off if they want to.It has been like this for a long time: https://github.com/quarkusio/quarkus/blob/d9ed7bc9a9b362cab20dc9c67559513efe9b81e6/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedSession.java#L109It won't catch lazy loading issues, but it will catch other blocking usage of the EM.
--StuartThanks,Sanne--StuartThanksSince our user are using our live coding facilities they see this right away, and say we make the error better “Did you forget to say @Blocking on your resource class or method?”
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/CAD%2BL2czo_wHrTB-s89xP6_mDX0%3Dv3uiiH_jpByDNaRr34oeZig%40mail.gmail.com.
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/CAD%2BL2cwKUDAUhhtQgBNbzXWOznSLdkPXsqqNrvQfXsLD_BLDxg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAFm4XO3-Ga5uxB3EcM8bH9QSi_sw_yF_JOQB6pySpDwCQ47D5w%40mail.gmail.com.
On Jun 27, 2021, at 12:47 PM, clement escoffier <clement....@gmail.com> wrote:
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAKW6fif%2B-dGqJOuKQjcSwjZCrTZxA7fKTsw3LNpjWCs4CmJihA%40mail.gmail.com.
If we wanted to make sure they have decided something, we could make the Quarkus rest extension agnostic. So basically, you have to explicitly declare NonBlocking or Blocking in one of the following places:1. Application - All JAX-RS methods in the app follow the setting (unless overridden)2. Resource class - all resource methods on the class follow the setting (unless overridden). Overrides 1 for that class.3. Method - apply this policy to just this method or override the default specified in to or 3Then we can throw an error at build time if any resource method is not specified one way or the other. Additionally, we could make the code generator specify a default of blocking like Stuart’s option 3, but I kinda prefer generating it on the resource class since then it’s not “hidden”; it’s right in front of you.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAJMo4%2Bdo8JcCkMLykmuM0iJONTt6u%3DmcarSz718D32Tm%3DuS8zg%40mail.gmail.com.
As you can imagine, I'm leaning towards the opposite.The current default provides a better overall experience. Changing it will introduce multiple "default" execution models as soon as you combine resteasy reactive with gRPC, or messaging, or redis…Providing an option, that the user can consciously configure, would be more beneficial.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAKW6fif0-e9Z4eL1B95uoTRTamQ77OD8eE6a__oTK6PcUYB%3D6Q%40mail.gmail.com.
As you can imagine, I'm leaning towards the opposite.The current default provides a better overall experience. Changing it will introduce multiple "default" execution models as soon as you combine resteasy reactive with gRPC, or messaging, or redis…
Providing an option, that the user can consciously configure, would be more beneficial.
On Jul 5, 2021, at 6:31 PM, Stuart Douglas <sdou...@redhat.com> wrote:
Providing an option, that the user can consciously configure, would be more beneficial.We can already do that for resteasy-reactive via the application class.
I don't think we need to update everything so that we have a single 'default execution model'. Even if a user wants RR to be blocking I don't think that would necessarily also apply to Reactive Messaging or gRPC.
1) Change the default to @Blocking, but in a smart way so we can still dispatch to @Async endpoints without switching to a worker thread
--
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/04efd2e3-2885-43f9-8f2b-e5e34a03eb93n%40googlegroups.com.
The basic reason is because you can never be sure just by looking at the return type.
Some users think that just wrapping a regular response in an async return type magically makes the whole thing run on the event loop.
Furthermore, returning a regular type doesn't mean anything blocked, you could just be returning some canned JSON response.
On Tuesday, July 6, 2021 at 10:36:49 AM UTC+2 gand...@redhat.com wrote:The basic reason is because you can never be sure just by looking at the return type.Well then we should design our contracts and programming model so you *can* be sure, no?Some users think that just wrapping a regular response in an async return type magically makes the whole thing run on the event loop.I don't understand this problem. On the contrary, it sounds like the behavior I would want, as described in your very next sentence:
@GET
public List<Fruit> get() {
return entityManager.createNamedQuery("Fruits.findAll", Fruit.class)
.getResultList();
}
@GET
public Uni<List<Fruit>> get() {
return Uni.createFrom().item(entityManager.createNamedQuery("Fruits.findAll", Fruit.class)
.getResultList());
}
Furthermore, returning a regular type doesn't mean anything blocked, you could just be returning some canned JSON response.Then return it in a Uni. One function call.
--
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/0777cb11-6ed8-4e5f-88ff-0eefbffff54en%40googlegroups.com.
I mean, you knew I was going to say this, because I always default to solving problems *using the type system*. Because I don't hate myself and my users.
On Tuesday, July 6, 2021 at 10:46:21 AM UTC+2 Gavin King wrote:On Tuesday, July 6, 2021 at 10:36:49 AM UTC+2 gand...@redhat.com wrote:The basic reason is because you can never be sure just by looking at the return type.Well then we should design our contracts and programming model so you *can* be sure, no?
--
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/c12fc8cb-ffc4-4480-b5a7-0613f665c5e4n%40googlegroups.com.
What I am saying is that some users seem to think simply changing it to ... will give them the benefits of Reactive.
In Quarkus as we don't have a way to peek into the implementation of the method, we have no idea what the user is actually doing to return that Uni.Furthermore, returning a regular type doesn't mean anything blocked, you could just be returning some canned JSON response.Then return it in a Uni. One function call.Sure, but why should I be forced to do that?
I know and I wish there were a consistent way to do this.The only way I see is if Quarkus could indeed play the role of the compiler here and look into what the method implementation is actually doing.
On Tuesday, July 6, 2021 at 10:52:56 AM UTC+2 gand...@redhat.com wrote:What I am saying is that some users seem to think simply changing it to ... will give them the benefits of Reactive.So the problem is that users think that even though WE HAVE A WHOLE PRODUCT CALLED HIBERNATE REACTIVE, they can get reactive by just calling Uni.createFrom() on regular Hibernate.I think it's clear that users who are that confused aren't really serious about reactive programming.I don't think this is a serious objection, frankly.
In Micronaut 1.x, Micronaut would attempt to automatically deduce the thread pool to use based on the return type of the controller method.
This approach caused some confusion and created a false association between reactive types and blocking operations.
In Quarkus as we don't have a way to peek into the implementation of the method, we have no idea what the user is actually doing to return that Uni.Furthermore, returning a regular type doesn't mean anything blocked, you could just be returning some canned JSON response.Then return it in a Uni. One function call.Sure, but why should I be forced to do that?Because it explicitly indicates my intent, instead of making the framework guess what I mean based on garbage fragile heuristics.
--
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/fa5c69a0-25b7-4f33-931f-ba17affbbf0an%40googlegroups.com.
--
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/fa5c69a0-25b7-4f33-931f-ba17affbbf0an%40googlegroups.com.
I don't agree. For Hibernate vs Hibernate Reactive sure, it should be very easy. But for other APIs, it's potentially not that obvious.
This is also what Micronaut figured out the hard way. From their docs:
In Micronaut 1.x, Micronaut would attempt to automatically deduce the thread pool to use based on the return type of the controller method.
This approach caused some confusion and created a false association between reactive types and blocking operations.
On Tuesday, July 6, 2021 at 11:04:22 AM UTC+2 gand...@redhat.com wrote:I don't agree. For Hibernate vs Hibernate Reactive sure, it should be very easy. But for other APIs, it's potentially not that obvious.Concrete example, please? Because I'm just not seeing it.It seems kinda intuitively obvious that reactive operations are going to return a reactive stream ... because, well, *that's our whole reactive programming model*.And if we have libs that are not fitting into that model, then that is a problem of the design of those libs and their (lack of) integration with the Quarkus programming model. (And *that* should be fixed.)This is also what Micronaut figured out the hard way. From their docs:In Micronaut 1.x, Micronaut would attempt to automatically deduce the thread pool to use based on the return type of the controller method.
So sounds like they got it right the first time, and then futzed it up. Silly them. Let's not reproduce their mistake.
This approach caused some confusion and created a false association between reactive types and blocking operations.
It's not a false association. It's correct.
--
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/62f46085-7585-47e8-b53b-f9fd3d635a89n%40googlegroups.com.
On Tue, Jul 6, 2021 at 12:10 PM Gavin King <gavin...@gmail.com> wrote:On Tuesday, July 6, 2021 at 11:04:22 AM UTC+2 gand...@redhat.com wrote:I don't agree. For Hibernate vs Hibernate Reactive sure, it should be very easy. But for other APIs, it's potentially not that obvious.Concrete example, please? Because I'm just not seeing it.It seems kinda intuitively obvious that reactive operations are going to return a reactive stream ... because, well, *that's our whole reactive programming model*.And if we have libs that are not fitting into that model, then that is a problem of the design of those libs and their (lack of) integration with the Quarkus programming model. (And *that* should be fixed.)This is also what Micronaut figured out the hard way. From their docs:In Micronaut 1.x, Micronaut would attempt to automatically deduce the thread pool to use based on the return type of the controller method.
So sounds like they got it right the first time, and then futzed it up. Silly them. Let's not reproduce their mistake.Exactly the opposite in my book. They tried what you proposed, they had in production for the entirety of the 0.x and 1.x releases and it turned out to not work in practice. It's an example to learn from if anything the way I see it
In an ideal world, sure. In practice, it's not a ironclad rule
Here is the issue that provides all the history of their decision: https://github.com/micronaut-projects/micronaut-core/issues/2215
--
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/0b269452-7e34-4b7c-9f4a-c53d4d982060n%40googlegroups.com.
--
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/18b1a957-486b-49c2-98f2-050e872aa19en%40googlegroups.com.
On Tue, Jul 6, 2021 at 12:21 PM Gavin King <gavin...@gmail.com> wrote:On Tuesday, July 6, 2021 at 11:17:23 AM UTC+2 gand...@redhat.com wrote:Here is the issue that provides all the history of their decision: https://github.com/micronaut-projects/micronaut-core/issues/2215I actually don't care at all what is the history of Micronaut's bad decisions.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CALeTM-%3DZjo0qYCYZ0sXbCd-vSXeUa_VVV0-7iwxUvQjq7wZPtA%40mail.gmail.com.
So let me get this straight: You trust users to take a random library (say for
example their favorite HTTP Client, or some NoSQL client) make their calls
(which you can't know how long they will take, as there could be IO, there
could be computation) and not wrap the return in a Uni thinking everything
will be fine?
Look, AFAIK, Mutiny already provides packaged functions to convert any sort of reactive result type into a Uni.It's not absurd to ask people to call one of these functions to convert things coming from other libs.Indeed, the main competing option, which is to use an annotation to do the job, instead of calling a function, is, well, simply not better.And I understand you want to be super-flexible, and work with what people are doing today, but ultimately that's not the philosophy we're supposed to be following here. We already agreed that Quarkus was supposed to have opinions, and our opinion on reactive is Mutiny.
Ultimately, asking people to use Mutiny is just asking them to do the thing that is going to make their lives easiest.
And if I'm using Mutiny the most natural thing in the world is to say "if the endpoint returns a Uni it's nonblocking".On Tuesday, July 6, 2021 at 11:22:34 AM UTC+2 gand...@redhat.com wrote:Absolutely, for our APIs. But we don't control what's come before, not the mental baggage people have accumulated over the years of Java development
--
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/58b208d2-880c-42a0-a728-41c86f78e3c0n%40googlegroups.com.
On Tue, Jul 6, 2021 at 12:32 PM Georgios Andrianakis <gand...@redhat.com> wrote:Because we can't learn from the mistakes of others? You know better than I do that that's not an epistemologically sound argument.
On Sat, 26 Jun 2021 at 16:49, Paul Carter-Brown <pa...@ukheshe.com> wrote:So the question I ask myself is this - would a developer who does not know or care about eventloops and blocking and reactive and worker pools, care about 8 microseconds?Well, 8ms doesn't seem like much, but it's still a 34% drop in perf: all alone it's peanuts, but under load it's a huge number.
--
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/CAKU9E9udsq%2BKDktnrqcA4LS8o1a4hzBP4uHxWw7wfT6_JeomoA%40mail.gmail.com.
@GET
@Path("/random")
public Integer random() {
return randomService.get();
}
How do I know if this "blocks" or not? As Clement says all the time, "blocking" is subjective to the system you are developing. If you are developing something that needs extremely high scalability, you can't get away with this call taking 100ms to complete as it will cause a build up of requests on the event loop thread.--
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/70236299-8ba8-4d24-b6b9-bda12b725b19n%40googlegroups.com.
On Tue, Jul 6, 2021 at 12:42 PM Gavin King <gavin...@gmail.com> wrote:On Tuesday, July 6, 2021 at 11:35:23 AM UTC+2 gand...@redhat.com wrote:On Tue, Jul 6, 2021 at 12:32 PM Georgios Andrianakis <gand...@redhat.com> wrote:Because we can't learn from the mistakes of others? You know better than I do that that's not an epistemologically sound argument.As I emphasized above, I would love to see a concrete example of the code you think would break this approach. An example from *Quarkus*, not from some other completely different ecosystem.@GET
How do I know if this "blocks" or not? As Clement says all the time, "blocking" is subjective to the system you are developing. If you are developing something that needs extremely high scalability, you can't get away with this call taking 100ms to complete as it will cause a build up of requests on the event loop thread.
@Path("/random")
public Integer random() {
return randomService.get();
}
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/bbff85f2-c9a2-4473-9249-a67869c5ef89n%40googlegroups.com.
On Tue, Jul 6, 2021 at 12:21 PM Gavin King <gavin...@gmail.com> wrote:On Tuesday, July 6, 2021 at 11:17:23 AM UTC+2 gand...@redhat.com wrote:Here is the issue that provides all the history of their decision: https://github.com/micronaut-projects/micronaut-core/issues/2215I actually don't care at all what is the history of Micronaut's bad decisions.I want to know: *why can't this work in Quarkus*.And you have so far not given me a single concrete example that would break it.So let me get this straight: You trust users to take a random library (say for example their favorite HTTP Client, or some NoSQL client) make their calls (which you can't know how long they will take, as there could be IO, there could be computation) and not wrap the return in a Uni thinking everything will be fine?Well sorry, but having answered so many user questions, I don't have the same faith you do.
----
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/18b1a957-486b-49c2-98f2-050e872aa19en%40googlegroups.com.
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/CALeTM-kH%3DtNO6Dz%2BoEbeEC%3DS01ERXgdPQNX557bLpPa2XsJ9sg%40mail.gmail.com.
So are we expecting developers to rewrite this as:public Uni<Integer> add(int a, int b) {
return Uni.createFrom().item(a + b);
}
--
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/5e8b215e-0ced-4022-aa6d-e9e530c3d58dn%40googlegroups.com.
On Tue, 6 Jul 2021 at 19:33, Georgios Andrianakis <gand...@redhat.com> wrote:On Tue, Jul 6, 2021 at 12:21 PM Gavin King <gavin...@gmail.com> wrote:On Tuesday, July 6, 2021 at 11:17:23 AM UTC+2 gand...@redhat.com wrote:Here is the issue that provides all the history of their decision: https://github.com/micronaut-projects/micronaut-core/issues/2215I actually don't care at all what is the history of Micronaut's bad decisions.I want to know: *why can't this work in Quarkus*.And you have so far not given me a single concrete example that would break it.So let me get this straight: You trust users to take a random library (say for example their favorite HTTP Client, or some NoSQL client) make their calls (which you can't know how long they will take, as there could be IO, there could be computation) and not wrap the return in a Uni thinking everything will be fine?Well sorry, but having answered so many user questions, I don't have the same faith you do.By that logic we should not provide @NonBlocking either, it's just as big a foot gun.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAO8YPTTu8T-Bo3Y%2B9snhh96onEYvHsQ4NCb_uPexR_cBxGytQQ%40mail.gmail.com.