-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Reactive REST Client breaks Hibernate Reactive Transactions #18977
Comments
The contract of 'sessionFactory.withSession() is to open a new session: the
Hibernate API does not make assumptions about scopes or contexts,
operations are explicit.
I guess we could make this clearer?
…On Fri, 23 Jul 2021, 21:47 quarkus-bot[bot], ***@***.***> wrote:
/cc @DavideD <https://github.com/DavideD>, @Sanne
<https://github.com/Sanne>, @gavinking <https://github.com/gavinking>,
@michalszynkiewicz <https://github.com/michalszynkiewicz>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#18977 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAKMTLFLENKTKLPHLKP6O3TZHINJANCNFSM5A4VMWKQ>
.
|
WDYM, @Sanne?
But I'm not sure why calling the rest client would change the Vert.x context. |
Yeah that's basically the question @gavinking. After the REST call returns the execution will resume on another event loop thread, but the session used to persist the entity is not in the context anymore. After a good night's sleep I can also answer my own question:
When there is no transaction, the |
OK so perhaps there's some way to avoid that. TBH it looks wrong to me, it's not what happens with the Vert.x SQL client, so I don't see why it should happen with the REST client (but surely I'm missing some subtleties). |
@michalszynkiewicz @geoand @FroMage Any idea why this would happen? |
Does the problem manifest in |
Just updated the reproducer and tested it with that version again. It does also exist in 2.1.0.Final. |
I'll try and have a look soon |
The problem here stems from the fact that when the response from the rest client comes back, it comes back on a different event-loop thread than the original one (essentially in RESTEasy Reactive when the result in ready, we resume processing by submitting to the event loop here - with executor created here). I thought that Vert.x had thread affinity so something like this could not happen. Apparently it's not the case |
Relates to quarkusio#18977 There are still issues though, as the vert.x pool is not enforcing affinity.
The vert.x io.vertx.core.net.impl.pool.SimpleConnectionPool does not appear to be maintaining affinity. |
So I assume we need some input from the Vertx folks? |
cc @cescoffier |
We've observed this in HR as well, and that's the reason behind additional design changes and assertions we have now. You should not make any assumptions regarding execturing thread but stick with using the vertx context. What is Reactive Resteasy doing which assumes "same thread" execution? |
Nothing. It's Hibernate Reactive that fails in this case because when the rest client comes back it's on a different Vert.x thread. |
oh, now I get it. Then it's probably my own fault, I'll need to review our internal assertions. Thanks, I'll check! |
@geoand sorry I'm confused - when you commented that I thought there was some trouble caused by my internal checks in All I see is that the context is lost when it's run on a different thread - I could go on and try to debug that but I'm puzzled that it's different than what you see? |
Nope, I didn't change anything.
All I did to see that the result was coming back on another thread was add a couple break points and print the current thread. When the rest-client was not being used, everything worked as expected because everything was being done on the same vert.x thread. However, when the rest client was added to the pipeline of operations (which it is in the reproducer), then once the result from that rest client call comes back, the rest of the pipeline seems to execute on another vert.x thread which I guess makes things fail. I have no knoweldge of what that is :) |
@geoand ok thanks for clarifying, that matches the same as what @DavideD and myself are seeing in debug. Ok now I understand what Stuart said about affinity. Yes we will need that http client which is invoked to not have the context being lost. This doesn't seem related to Hibernate Reactive and I'm not familiar with these integrations.. who can own this? |
I always took it for granted that Vert.x had thread affinity, but that doesn't seem to be the case. I assume we would need input from the Vert.x folks on this one. |
Yea, I think this needs input from the Vert.x guys. I think it is a bug in SimpleConnectionPool but I am not 100% sure what the expected semantics are. |
Vert.x does have thread affinity in at least some cases (for the SQL client it does, assuming I recall correctly what @vietj told me) but HR doesn't depend on it. All we require is that the Vert.x context is preserved. |
OK, so is the Vert.x context preserved then? |
I assume not, otherwise this would work. So it's not "just" a thread affinity issue. Although I'm pretty sure we also need thread affinity to not get two parallel executions of the same context. |
I've passed on the question to the Vert.x team on discord. Pretty sure @cescoffier is on PTO: https://discord.com/channels/751380286071242794/751398938459766895/872058623394738236 |
It isn't. We have a context created and associated to the first thread, but after the REST client is invoked, subsequent operations are executed on a different thread and the original context is gone. |
Actually, we get notified from the client on a |
@FroMage thanks for that analysis. Are you going to take care of the issue? |
I probably can. |
Thanks! |
Relates to quarkusio#18977 There are still issues though, as the vert.x pool is not enforcing affinity.
Fixes quarkusio#18977 (cherry picked from commit 8dd0af4)
Fixes quarkusio#18977 (cherry picked from commit 8dd0af4)
Describe the bug
When combining the Reactive REST client with Hibernate Reactive, the Reactive REST client seems to break Context Propagation, leading to Hibernate Transactions not working as intended.
Expected behavior
Using Reactive REST Client does not have any negative effects on Hibernate Reactive
Actual behavior
Using Reactive REST Client will break Hibernate Reactive Transactions because a call to
sessionFactory.withSession()
within an existing transaction will result in a new session being created instead of re-using the previously existing session residing in context.How to Reproduce?
Reproducer: https://github.com/markusdlugi/hibernate-reactive-with-transaction (don't get confused by the naming)
Steps to reproduce the behavior:
http://localhost:8080/test
. It will fail withjava.lang.IllegalStateException: Couldn't find author 1
TestResource
line 48). If you repeat the test, it will now work, you get an author and some books..withTransaction((session, tx)
in line 43 with.withSession(session
. The test will now work again, even though the REST call is still in place.It seems like after the REST call, the
session2
in the reproducer is not the same session assession1
where the entity was initially persisted. This leads to the error. Seems like the Reactive REST client messes up the context propagation.Not sure why the example works when getting rid of the transaction entirely, though.
Output of
uname -a
orver
Microsoft Windows [Version 10.0.18363.1556]
Output of
java -version
OpenJDK 64-Bit Server VM Corretto-11.0.10.9.1 (build 11.0.10+9-LTS, mixed mode)
GraalVM version (if different from Java)
N/A
Quarkus version or git rev
2.0.3.Final
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.6.3
Additional information
Possibly related to #16949? But this one seems more severe because you cannot mix Hibernate Reactive Transactions and the REST client at all.
The text was updated successfully, but these errors were encountered: