spring-graphql icon indicating copy to clipboard operation
spring-graphql copied to clipboard

Use ReactorContext from ThreadLocalAccessor in WebGraphQlHandlerInterceptor

Open alejandropm-san opened this issue 3 years ago • 8 comments

Hi, I want to access the values saved in ReactorContext by my ThreadLocalAccessor impl in a WebGraphQlHandlerInterceptor, but ReactorContextManager save them inside a map using a private Key name and from what i could see there isn't a way for retrieving those values without declaring again the Key name in my project. Am I right? Is there going to be a better way to do this?

As i understood, ThreadLocalAccessor extract and restore Servlet context from/to DataFetchers, what about WebGraphQlHandlerInterceptor? Am i missing something?

Thanks in advance.

alejandropm-san avatar Apr 04 '22 16:04 alejandropm-san

I presume that you want to access them as ThreadLocal values? Currently we don't restore context for interceptors but we can do that.

rstoyanchev avatar Apr 12 '22 09:04 rstoyanchev

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar Apr 19 '22 09:04 spring-projects-issues

Hi again, thank you for answering. I could review the code to better understand what was happening and explain it clearly:

I am using a WebGraphQlHandlerInterceptor to include some values in context with request/response info. For Reactive apps was everything ok, but for Servlet apps i was using ThreadLocal contexts and then notice these can be empty because of changing the execution thread. Then i used Reactor Context to obtain ThreadLocal context values as i have a ThreadLocalAccessor to save them, but the access to these values is not as easy as expected because they are included in a Map with a key "...ReactorContextManager.THREAD_VALUES_ACCESSOR" which has private access scope. So i had to define this key in my interceptor and read it directly from Context.

I was expecting maybe a public static method in ReactorContextManager to extract that saved map, or even better to extract a value saved with a concrete ThreadLocalAccessor. About your proposed solution, restoring context for interceptors sounds great but as i understand, thread may change in async interceptors, and saving/restoring contexts in every interceptor doesn't seem optimal, is it?

alejandropm-san avatar Apr 25 '22 15:04 alejandropm-san

I'm a bit unclear on what exactly you're trying to achieve.

It sounds to me like you have some Threadlocal values in Spring MVC and you want to use a WebGraphQlInterceptor to add them to the GraphQLContext? I wonder if you need to do that though since those ThreadLocal values are captured and will be restored for data fetchers to access.

If you could please take a step back and explain the use case and what your goal is, without referring to a solution and details like ThreadLocalAccessor or ReactorContext, which are not intended to be used directly by applications.

rstoyanchev avatar May 05 '22 06:05 rstoyanchev

I'm sorry for being unclear with my explanation.

I want to save something in a ThreadLocal object of mine based on the info of the WebGraphQlResponse (to check if there are errors or not), and for every response (that's important, as i need a solution for any mapping/dataFetcher).

I found that WebGraphQlInterceptor can be useful for this, but as i read here in Spring GraphQl doc an async interceptor in Spring MVC app could change the execution to a different thread, so i can't use ThreadLocal values directly.

Let me know if it's ok up to here or there is something wrong, thanks.

alejandropm-san avatar May 09 '22 09:05 alejandropm-san

At what layer, level, or component is the ThreadLocal created? At what layer, level, or component do you want to modify it? At what layer, level, or component do you want to access it?

Please, be as specific as you can be, e.g. "Servlet filter on the way in", etc.

rstoyanchev avatar May 13 '22 09:05 rstoyanchev

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar May 20 '22 09:05 spring-projects-issues

We create the ThreadLocal object in a Servlet filter, we want to modify it in an WebGraphQlHandlerInterceptor based on GraphQl response, and want to access it in another Servlet filter before return statement.

alejandropm-san avatar May 23 '22 10:05 alejandropm-san

Thanks for the clarification. That makes the scenario clear.

After #459, for the upcoming 1.1 release, you can register a ThreadLocalAccessor with a key, and the ThreadLocal value will be inserted into the Reactor context under that same key. So a WebGraphQlHandlerInterceptor can access this value from the Reactor context and it can also change the value in the Reactor context.

That said, currently we don't update the ThreadLocal after the call to the WebGraphQlHandlerInterceptor chain, which means that the Filter chain won't see any change on the way out. We could make that a feature, or alternatively, you could use WebGraphQlHandlerInterceptor to add HTTP response headers, if that's all you need to do from the Servlet Filter.

rstoyanchev avatar Oct 24 '22 15:10 rstoyanchev

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar Oct 31 '22 15:10 spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

spring-projects-issues avatar Nov 07 '22 15:11 spring-projects-issues