[jira] [Commented] (CXF-8303) MP: Context propagation impossible using AsyncInvocationInterceptorFactory

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Commented] (CXF-8303) MP: Context propagation impossible using AsyncInvocationInterceptorFactory

jagadeesh (Jira)

    [ https://issues.apache.org/jira/browse/CXF-8303?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17144578#comment-17144578 ]

Andriy Redko commented on CXF-8303:
-----------------------------------

Hey [~baiglin] ,

So you could easily use the same executor service for both MP and CXF Work Queue, just create the extension for `AutomaticWorkQueue`, for example (the snippet is a bit simplified):

 
{code:java}
  private static Extension createAutomaticWorkQueue(ExecutorService executor) {
      return new Extension(AutomaticWorkQueue.class) {
          public Object getLoadedObject() {
              return new AutomaticWorkQueue() {
                @Override
                public void execute(Runnable work, long timeout) {
                    executor.execute(work);
                }

                @Override
                public void schedule(Runnable work, long delay) {
                    executor.execute(work);
                }

                @Override
                public void execute(Runnable command) {
                    executor.execute(command);
                }
               
                @Override
                public String getName() {
                    return "default";
                }                

                @Override
                public void shutdown(boolean processRemainingWorkItems) {
                    executor.shutdown();
                   
                }                
               
                @Override
                public boolean isShutdown() {
                    return service.isShutdown();
                }
              };
          }          

          public Extension cloneNoObject() {
              return this;
          }
      };
  }
{code}
And register it, for example:
{code:java}
final ExecutorService executor = Executors.newCachedThreadPool();
ExtensionRegistry.addExtensions(Arrays.asList(createAutomaticWorkQueue(executor )));{code}
The same executor could be passed to `MicroProfileClientFactoryBean`, for example:
{code:java}
MicroProfileClientFactoryBean factoryBean = new MicroProfileClientFactoryBean(config, URI.create("http://localhost:" + port + "/").toString(), Library.class, executor, new TLSConfiguration());

{code}
In this case, you should have total control over the thread pool and context propagation.

 

> MP: Context propagation impossible using  AsyncInvocationInterceptorFactory
> ---------------------------------------------------------------------------
>
>                 Key: CXF-8303
>                 URL: https://issues.apache.org/jira/browse/CXF-8303
>             Project: CXF
>          Issue Type: Bug
>          Components: MicroProfile
>            Reporter: Baptiste AIGLIN
>            Assignee: Andriy Redko
>            Priority: Major
>         Attachments: cxf-context-reproducer.zip
>
>
> Hello!
> We are deeply working using the Microprofile rest client implementation of CXF and we have trouble with the context propagation between threads.
> We have implemented AsyncInvocationInterceptorFactory and use it to propagate threadLocal context on the receiving thread after an asynchronous call, but I found some problem due to this:
>  * Call is performed from the main thread
>  * Response is handled in the CXF work queue, that execute the interceptor chain and propagate the thread local context correctly
>  * During the chain execution the response entity is set to notify the future but it then execute in the executor thread (By default ForkJoinPool)
> So the fact that the future is returned using the *Async method of the CompletableFuture makes the next stage to execute in the executor (ForkJoinPool) thread where the context was not propagated.
>  
> I am not saying this is simple since it is not, but could it be possible to return the future itself rather than using the custom executor (ForkJoinPool), and instead use the custom executor the same way it is used for JAX-WS where I think it is set as Executor in the exchange and later retrieve by the conduit to perform the response execution ?
> Also we noticed due to this that as soon as the response is notified, the full interceptor chain is not yet executed and continue to execute in the workqueue thread while the next stage is starting to execute in the ForkJoinPool thread.
> I hope I was clear enough. I add a reproducer with the dummy solution I could come up with to see what I am asking is at least fixing the problem. Also I know a fix is already ongoing here https://issues.apache.org/jira/browse/CXF-8242 but is using thenApplyAsync(res -> (T)res[0], executor), so should not fix the problem.
> Thanks a lot



--
This message was sent by Atlassian Jira
(v8.3.4#803005)