spring-data-commons icon indicating copy to clipboard operation
spring-data-commons copied to clipboard

Why RepositoryMethodInvoker.doInvokeReactiveToSuspended strips coroutine continuation?

Open ojh3636 opened this issue 3 years ago • 10 comments

[Version: spring-data-commons-2.4.13]

Hi, I have quesiton during digging the behavior of r2dbc, CoroutineCrudRepository.

First of all, What I want to do is logging query with some metadata that only can be retrieved from outer reactor or coroutine context (ex> ipath, eventId, spanId ..).

What I try first is

  1. Register ProxyConnectionFactory and register listener to log query.
  2. I wrote the code inside proxy listener that obtain "currentCoroutineContext[ReactorContext]" and use them when logging

But I found that "currentCoroutineContext[ReactorContext]" returns empty.

And I digging the repository behavior and I encounter below code. image Does the code in L168 means that all methods that are invoked in repository interface loose outer ractor or coroutine context?

Is there any way that can pass the outer coroutine or reactor context into repository method invokation?

Thank you.

ojh3636 avatar Dec 20 '21 09:12 ojh3636

I moved the ticket to Spring Data Commons as the code lives there.

mp911de avatar Jan 17 '22 10:01 mp911de

doInvokeReactiveToSuspended adapts a coroutine call to a reactive one by calling the backing reactive method that returns a Publisher. The expectation is that AwaitKt.awaitSingleOrNull(…) accepting the Continuation parameter subscribes correctly to the publisher and propagates the context correctly. If the context gets lost, then this is a bug. Maybe @sdeleuze can provide more insights how we can address the context loss.

mp911de avatar Jan 17 '22 10:01 mp911de

Thank you for answer. To be clear the AwaitKt.awaitSingleOrNull(result, continuation) properly propagate context after reactive repository works(like select, update,..). But what I want to do is, want to capture the context "inside" the reactive repository works. Now, the context propagated as below

Some Code with Context -> repository method invoke without context -> after code with context

But I want to get parent context in repository method.

ojh3636 avatar Jan 19 '22 02:01 ojh3636

Can you provide an example (minimal reproducer) of what you're trying to achieve? The textual description doesn't really make that clear. With a reproducer, we can actually check what's required to make it work.

mp911de avatar Jan 19 '22 09:01 mp911de

Ok I'ill make some reproducable example project! Thank you

ojh3636 avatar Jan 19 '22 10:01 ojh3636

Probably related: https://github.com/spring-projects/spring-framework/pull/27308

mp911de avatar Jan 20 '22 10:01 mp911de

@ojh3636 Could you please provide a reproducer?

sdeleuze avatar Mar 15 '22 08:03 sdeleuze

@mp911de I think invoking ReactiveInvocationListenerDecorator#decorate with the Continuation removed is indeed incorrect, not sure yet what should be done instead.

sdeleuze avatar Mar 15 '22 08:03 sdeleuze

@ojh3636 Any chance you could provide a reproducer?

sdeleuze avatar Aug 19 '22 07:08 sdeleuze

@mp911de I have a potential fix (waiting for Kotlin team feedback) on https://github.com/sdeleuze/spring-framework/commit/gh-27308, it will be worth to test if this issue still occur with those changes (using my branch or waiting it to be merged in Spring Framework).

sdeleuze avatar Feb 02 '23 14:02 sdeleuze