You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by cocorossello <co...@gmail.com> on 2017/01/25 10:56:13 UTC

MDC and @Asynchronous

Hi,

I'm using logback's MDC to setup some logging info accross my application
(jsessionid and other stuff). Our application uses lots of @Asynchronous
methods. Since logback 1.1.3 MDC context is not propagated to child threads.

Is there any way to customise the asynchronous thread pool executor so I can
propagate manually the context as logback docs says?

/MDC And Managed Threads

A copy of the mapped diagnostic context can not always be inherited by
worker threads from the initiating thread. This is the case when
java.util.concurrent.Executors is used for thread management. For instance,
newCachedThreadPool method creates a ThreadPoolExecutor and like other
thread pooling code, it has intricate thread creation logic.

In such cases, it is recommended that MDC.getCopyOfContextMap() is invoked
on the original (master) thread before submitting a task to the executor.
When the task runs, as its first action, it should invoke
MDC.setContextMapValues() to associate the stored copy of the original MDC
values with the new Executor managed thread./

(or should I just forget MDC and think of another "context" mechanism?)



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Hi,

I wish we could use 1 minute timeout... travel industry is not the most
advanced tecnologically.... some bookings take as long as 2 minutes and
timeouts are very frequent. Some providers even use screen scrapping, so
they are not very reliable.

We use different timeouts depending on the operation: 1 minute for search,
90 seconds to perform booking, etc.

Caching is another hard topic as providers are using "stateful" web services
with session. You need a session id to book a previous search, prices expire
often, specially with flights. We do cache some searches, but it's a hard
topic.

Thanks for your support, it's been very useful



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680979.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
2017-01-29 15:41 GMT+01:00 cocorossello <co...@gmail.com>:

> Hi,
>
> I see the problem.
>
> I don't really understand why max is 100
>
>
a pool will increase the number of threads once the queue is full so you
will get 101 threads when you will have (100 running tasks + 150000 waiting
ones + 1) which is a number you dont hit in your test


> On Sun, Jan 29, 2017 at 3:27 PM, Romain Manni-Bucau [via TomEE & OpenEJB] <
> ml-node+s979440n4680972h59@n4.nabble.com> wrote:
>
> > I think you just ensured to lock yourself - but agree it is well hidden
> > ;).
> >
> > You have one layer waiting for N sub async tasks to be done but next
> layer
> > submits a lot of task and first layer keeps continuing so you just block
> > yourself since at some point second layer is blocked by first layer which
> > filled the pool. Not it is not a deadlock by itself but just a code logic
> > lock if that phrasing means anything.
> >
> > Note that configuring a queue that big will always queue instead of
> > increasing the pool size which will always be 100 and never 700
> (reference
> > to your config). Not an issue but means Max=100 concretely. It means that
> > if com.tr2.test.MyStateless#sayHello submits 99 tasks instead of 200 the
> > blocking will likely not happen that easily if you followed me.
> >
> > Said otherwise: it is not linked to tomee but the code design (nesting
> > thread pool tasks between them for a *same* executor is very dangerous.
> >
> > Here a simpler example: you have an executor of core=1, queue=1, first
> > task
> > submits 1 other tasks. You submitted therefore 2 tasks which passes cause
> > it fills our core and queue but doesn't overpass it. However the second
> > task submitted by the first one will never be executed and therefore the
> > first task will keep waiting for it except if you have a timeout. In such
> > a
> > case the "facade"/first task will fail and let the child one be executed
> > and release slowly the pool.
> >
> > Timeouts are key with thread pools.
> >
> > Side note, this works in the interceptor:
> >
> > @Resource(name = "TravelcAsynchronousPool")
> > private ManagedExecutorService executor;
> >
> >
> >
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://blog-rmannibucau.rhcloud.com> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <https://github.com/
> > rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
> > <https://javaeefactory-rmannibucau.rhcloud.com>
> >
> > 2017-01-29 13:48 GMT+01:00 cocorossello <[hidden email]
> > <http:///user/SendEmail.jtp?type=node&node=4680972&i=0>>:
> >
> > > Hi,
> > >
> > > I'm running into problems with this, I think it might be another
> openejb
> > > bug.
> > >
> > > If I have two levels of EJB @async threads get stuck  at:
> > >
> > > at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
> > >     at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
> > >     at java.util.concurrent.FutureTask.get(FutureTask.java:191)
> > >     at org.apache.openejb.threads.future.CUFuture.get(CUFuture.
> java:55)
> > >     at
> > > com.tr2.util.interceptor.async.FutureDelegator.get(
> > > FutureDelegator.java:19)
> > >
> > > The setup is very simple
> > > someStateless -> AsyncTask1 -> asyncTask2
> > >
> > > I made an ApplicationComposer test (AsyncInterceptorIT) in that github
> > > project (with latest SNAPSHOT)
> > >
> > > https://github.com/cocorossello/tomee-example
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > --
> > > View this message in context: http://tomee-openejb.979440.
> > > n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680971.html
> > > Sent from the TomEE Users mailing list archive at Nabble.com.
> > >
> >
> >
> > ------------------------------
> > If you reply to this email, your message will be added to the discussion
> > below:
> > http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-
> > tp4680927p4680972.html
> > To unsubscribe from MDC and @Asynchronous, click here
> > <http://tomee-openejb.979440.n4.nabble.com/template/
> NamlServlet.jtp?macro=unsubscribe_by_code&node=4680927&code=
> Y29jb3Jvc3NlbGxvQGdtYWlsLmNvbXw0NjgwOTI3fC05Mzc2MzQ4MzY=>
> > .
> > NAML
> > <http://tomee-openejb.979440.n4.nabble.com/template/
> NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
> >
>
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680973.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Hi,

I see the problem.

I don't really understand why max is 100

On Sun, Jan 29, 2017 at 3:27 PM, Romain Manni-Bucau [via TomEE & OpenEJB] <
ml-node+s979440n4680972h59@n4.nabble.com> wrote:

> I think you just ensured to lock yourself - but agree it is well hidden
> ;).
>
> You have one layer waiting for N sub async tasks to be done but next layer
> submits a lot of task and first layer keeps continuing so you just block
> yourself since at some point second layer is blocked by first layer which
> filled the pool. Not it is not a deadlock by itself but just a code logic
> lock if that phrasing means anything.
>
> Note that configuring a queue that big will always queue instead of
> increasing the pool size which will always be 100 and never 700 (reference
> to your config). Not an issue but means Max=100 concretely. It means that
> if com.tr2.test.MyStateless#sayHello submits 99 tasks instead of 200 the
> blocking will likely not happen that easily if you followed me.
>
> Said otherwise: it is not linked to tomee but the code design (nesting
> thread pool tasks between them for a *same* executor is very dangerous.
>
> Here a simpler example: you have an executor of core=1, queue=1, first
> task
> submits 1 other tasks. You submitted therefore 2 tasks which passes cause
> it fills our core and queue but doesn't overpass it. However the second
> task submitted by the first one will never be executed and therefore the
> first task will keep waiting for it except if you have a timeout. In such
> a
> case the "facade"/first task will fail and let the child one be executed
> and release slowly the pool.
>
> Timeouts are key with thread pools.
>
> Side note, this works in the interceptor:
>
> @Resource(name = "TravelcAsynchronousPool")
> private ManagedExecutorService executor;
>
>
>
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://blog-rmannibucau.rhcloud.com> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/
> rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
> <https://javaeefactory-rmannibucau.rhcloud.com>
>
> 2017-01-29 13:48 GMT+01:00 cocorossello <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4680972&i=0>>:
>
> > Hi,
> >
> > I'm running into problems with this, I think it might be another openejb
> > bug.
> >
> > If I have two levels of EJB @async threads get stuck  at:
> >
> > at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
> >     at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
> >     at java.util.concurrent.FutureTask.get(FutureTask.java:191)
> >     at org.apache.openejb.threads.future.CUFuture.get(CUFuture.java:55)
> >     at
> > com.tr2.util.interceptor.async.FutureDelegator.get(
> > FutureDelegator.java:19)
> >
> > The setup is very simple
> > someStateless -> AsyncTask1 -> asyncTask2
> >
> > I made an ApplicationComposer test (AsyncInterceptorIT) in that github
> > project (with latest SNAPSHOT)
> >
> > https://github.com/cocorossello/tomee-example
> >
> >
> >
> >
> >
> >
> >
> >
> > --
> > View this message in context: http://tomee-openejb.979440.
> > n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680971.html
> > Sent from the TomEE Users mailing list archive at Nabble.com.
> >
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
> http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-
> tp4680927p4680972.html
> To unsubscribe from MDC and @Asynchronous, click here
> <http://tomee-openejb.979440.n4.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=4680927&code=Y29jb3Jvc3NlbGxvQGdtYWlsLmNvbXw0NjgwOTI3fC05Mzc2MzQ4MzY=>
> .
> NAML
> <http://tomee-openejb.979440.n4.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>




--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680973.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
yes, concretely (to adapt to your case) you will need to play with:

1. timeout (not something a small slow down can hit but not something too
big, ~1mn is not bad for slow providers)
2. caching (jcache in local mode is great)
3. memory

Allocating blindly threads will lead to out of memory (try to have
core=15000 tasks in your test should be close to make it happening)



Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-29 15:51 GMT+01:00 cocorossello <co...@gmail.com>:

> Sorry, I hit enter too early.
>
>
>
>
> I see the problem.
>
>
> I didn't have that problem with @Asynchronous, but it is probably because I
> didn't properly test it and we haven't hit max.
>
> Our application searches for several type of products (flights, trains,
> hotels, tickets, transfers, cars) in several different providers for each
> type of product. (that would be about 20-25 threads opened per search).
>
> -For each type of product we open a thread (product thread)
>    -For each provider of that specific product we open a thread to search
> the product (search thread)
>    -We mix all results from each provider in the product thread
>
>
>
> So I think that the best solution for us would be to use different pools
> for each task and always use timeouts (we have proper timeouts in all web
> service searchs, I didn't think about this case).
>
>
>
> On Sun, Jan 29, 2017 at 3:43 PM, Vicente Rossello <co...@gmail.com>
> wrote:
>
> > Hi,
> >
> > I see the problem.
> >
> > I don't really understand why max is 100
> >
> > On Sun, Jan 29, 2017 at 3:27 PM, Romain Manni-Bucau [via TomEE & OpenEJB]
> > <ml...@n4.nabble.com> wrote:
> >
> >> I think you just ensured to lock yourself - but agree it is well hidden
> >> ;).
> >>
> >> You have one layer waiting for N sub async tasks to be done but next
> >> layer
> >> submits a lot of task and first layer keeps continuing so you just block
> >> yourself since at some point second layer is blocked by first layer
> which
> >> filled the pool. Not it is not a deadlock by itself but just a code
> logic
> >> lock if that phrasing means anything.
> >>
> >> Note that configuring a queue that big will always queue instead of
> >> increasing the pool size which will always be 100 and never 700
> >> (reference
> >> to your config). Not an issue but means Max=100 concretely. It means
> that
> >> if com.tr2.test.MyStateless#sayHello submits 99 tasks instead of 200
> the
> >> blocking will likely not happen that easily if you followed me.
> >>
> >> Said otherwise: it is not linked to tomee but the code design (nesting
> >> thread pool tasks between them for a *same* executor is very dangerous.
> >>
> >> Here a simpler example: you have an executor of core=1, queue=1, first
> >> task
> >> submits 1 other tasks. You submitted therefore 2 tasks which passes
> cause
> >> it fills our core and queue but doesn't overpass it. However the second
> >> task submitted by the first one will never be executed and therefore the
> >> first task will keep waiting for it except if you have a timeout. In
> such
> >> a
> >> case the "facade"/first task will fail and let the child one be executed
> >> and release slowly the pool.
> >>
> >> Timeouts are key with thread pools.
> >>
> >> Side note, this works in the interceptor:
> >>
> >> @Resource(name = "TravelcAsynchronousPool")
> >> private ManagedExecutorService executor;
> >>
> >>
> >>
> >>
> >> Romain Manni-Bucau
> >> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >> <https://blog-rmannibucau.rhcloud.com> | Old Blog
> >> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >> LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
> >> <https://javaeefactory-rmannibucau.rhcloud.com>
> >>
> >> 2017-01-29 13:48 GMT+01:00 cocorossello <[hidden email]
> >> <http:///user/SendEmail.jtp?type=node&node=4680972&i=0>>:
> >>
> >> > Hi,
> >> >
> >> > I'm running into problems with this, I think it might be another
> >> openejb
> >> > bug.
> >> >
> >> > If I have two levels of EJB @async threads get stuck  at:
> >> >
> >> > at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
> >> >     at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
> >> >     at java.util.concurrent.FutureTask.get(FutureTask.java:191)
> >> >     at org.apache.openejb.threads.future.CUFuture.get(CUFuture.
> java:55)
> >>
> >> >     at
> >> > com.tr2.util.interceptor.async.FutureDelegator.get(
> >> > FutureDelegator.java:19)
> >> >
> >> > The setup is very simple
> >> > someStateless -> AsyncTask1 -> asyncTask2
> >> >
> >> > I made an ApplicationComposer test (AsyncInterceptorIT) in that github
> >> > project (with latest SNAPSHOT)
> >> >
> >> > https://github.com/cocorossello/tomee-example
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > --
> >> > View this message in context: http://tomee-openejb.979440.
> >> > n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680971.html
> >> > Sent from the TomEE Users mailing list archive at Nabble.com.
> >> >
> >>
> >>
> >> ------------------------------
> >> If you reply to this email, your message will be added to the discussion
> >> below:
> >> http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchrono
> >> us-tp4680927p4680972.html
> >> To unsubscribe from MDC and @Asynchronous, click here
> >> <http://tomee-openejb.979440.n4.nabble.com/template/
> NamlServlet.jtp?macro=unsubscribe_by_code&node=4680927&code=
> Y29jb3Jvc3NlbGxvQGdtYWlsLmNvbXw0NjgwOTI3fC05Mzc2MzQ4MzY=>
> >> .
> >> NAML
> >> <http://tomee-openejb.979440.n4.nabble.com/template/
> NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
> >>
> >
> >
>
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680975.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Sorry, I hit enter too early.




I see the problem.


I didn't have that problem with @Asynchronous, but it is probably because I
didn't properly test it and we haven't hit max.

Our application searches for several type of products (flights, trains,
hotels, tickets, transfers, cars) in several different providers for each
type of product. (that would be about 20-25 threads opened per search).

-For each type of product we open a thread (product thread)
   -For each provider of that specific product we open a thread to search
the product (search thread)
   -We mix all results from each provider in the product thread



So I think that the best solution for us would be to use different pools
for each task and always use timeouts (we have proper timeouts in all web
service searchs, I didn't think about this case).



On Sun, Jan 29, 2017 at 3:43 PM, Vicente Rossello <co...@gmail.com>
wrote:

> Hi,
>
> I see the problem.
>
> I don't really understand why max is 100
>
> On Sun, Jan 29, 2017 at 3:27 PM, Romain Manni-Bucau [via TomEE & OpenEJB]
> <ml...@n4.nabble.com> wrote:
>
>> I think you just ensured to lock yourself - but agree it is well hidden
>> ;).
>>
>> You have one layer waiting for N sub async tasks to be done but next
>> layer
>> submits a lot of task and first layer keeps continuing so you just block
>> yourself since at some point second layer is blocked by first layer which
>> filled the pool. Not it is not a deadlock by itself but just a code logic
>> lock if that phrasing means anything.
>>
>> Note that configuring a queue that big will always queue instead of
>> increasing the pool size which will always be 100 and never 700
>> (reference
>> to your config). Not an issue but means Max=100 concretely. It means that
>> if com.tr2.test.MyStateless#sayHello submits 99 tasks instead of 200 the
>> blocking will likely not happen that easily if you followed me.
>>
>> Said otherwise: it is not linked to tomee but the code design (nesting
>> thread pool tasks between them for a *same* executor is very dangerous.
>>
>> Here a simpler example: you have an executor of core=1, queue=1, first
>> task
>> submits 1 other tasks. You submitted therefore 2 tasks which passes cause
>> it fills our core and queue but doesn't overpass it. However the second
>> task submitted by the first one will never be executed and therefore the
>> first task will keep waiting for it except if you have a timeout. In such
>> a
>> case the "facade"/first task will fail and let the child one be executed
>> and release slowly the pool.
>>
>> Timeouts are key with thread pools.
>>
>> Side note, this works in the interceptor:
>>
>> @Resource(name = "TravelcAsynchronousPool")
>> private ManagedExecutorService executor;
>>
>>
>>
>>
>> Romain Manni-Bucau
>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>> <https://blog-rmannibucau.rhcloud.com> | Old Blog
>> <http://rmannibucau.wordpress.com> | Github <
>> https://github.com/rmannibucau> |
>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
>> <https://javaeefactory-rmannibucau.rhcloud.com>
>>
>> 2017-01-29 13:48 GMT+01:00 cocorossello <[hidden email]
>> <http:///user/SendEmail.jtp?type=node&node=4680972&i=0>>:
>>
>> > Hi,
>> >
>> > I'm running into problems with this, I think it might be another
>> openejb
>> > bug.
>> >
>> > If I have two levels of EJB @async threads get stuck  at:
>> >
>> > at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
>> >     at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
>> >     at java.util.concurrent.FutureTask.get(FutureTask.java:191)
>> >     at org.apache.openejb.threads.future.CUFuture.get(CUFuture.java:55)
>>
>> >     at
>> > com.tr2.util.interceptor.async.FutureDelegator.get(
>> > FutureDelegator.java:19)
>> >
>> > The setup is very simple
>> > someStateless -> AsyncTask1 -> asyncTask2
>> >
>> > I made an ApplicationComposer test (AsyncInterceptorIT) in that github
>> > project (with latest SNAPSHOT)
>> >
>> > https://github.com/cocorossello/tomee-example
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > --
>> > View this message in context: http://tomee-openejb.979440.
>> > n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680971.html
>> > Sent from the TomEE Users mailing list archive at Nabble.com.
>> >
>>
>>
>> ------------------------------
>> If you reply to this email, your message will be added to the discussion
>> below:
>> http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchrono
>> us-tp4680927p4680972.html
>> To unsubscribe from MDC and @Asynchronous, click here
>> <http://tomee-openejb.979440.n4.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=4680927&code=Y29jb3Jvc3NlbGxvQGdtYWlsLmNvbXw0NjgwOTI3fC05Mzc2MzQ4MzY=>
>> .
>> NAML
>> <http://tomee-openejb.979440.n4.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>>
>
>




--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680975.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
I think you just ensured to lock yourself - but agree it is well hidden ;).

You have one layer waiting for N sub async tasks to be done but next layer
submits a lot of task and first layer keeps continuing so you just block
yourself since at some point second layer is blocked by first layer which
filled the pool. Not it is not a deadlock by itself but just a code logic
lock if that phrasing means anything.

Note that configuring a queue that big will always queue instead of
increasing the pool size which will always be 100 and never 700 (reference
to your config). Not an issue but means Max=100 concretely. It means that
if com.tr2.test.MyStateless#sayHello submits 99 tasks instead of 200 the
blocking will likely not happen that easily if you followed me.

Said otherwise: it is not linked to tomee but the code design (nesting
thread pool tasks between them for a *same* executor is very dangerous.

Here a simpler example: you have an executor of core=1, queue=1, first task
submits 1 other tasks. You submitted therefore 2 tasks which passes cause
it fills our core and queue but doesn't overpass it. However the second
task submitted by the first one will never be executed and therefore the
first task will keep waiting for it except if you have a timeout. In such a
case the "facade"/first task will fail and let the child one be executed
and release slowly the pool.

Timeouts are key with thread pools.

Side note, this works in the interceptor:

@Resource(name = "TravelcAsynchronousPool")
private ManagedExecutorService executor;




Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-29 13:48 GMT+01:00 cocorossello <co...@gmail.com>:

> Hi,
>
> I'm running into problems with this, I think it might be another openejb
> bug.
>
> If I have two levels of EJB @async threads get stuck  at:
>
> at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
>     at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
>     at java.util.concurrent.FutureTask.get(FutureTask.java:191)
>     at org.apache.openejb.threads.future.CUFuture.get(CUFuture.java:55)
>     at
> com.tr2.util.interceptor.async.FutureDelegator.get(
> FutureDelegator.java:19)
>
> The setup is very simple
> someStateless -> AsyncTask1 -> asyncTask2
>
> I made an ApplicationComposer test (AsyncInterceptorIT) in that github
> project (with latest SNAPSHOT)
>
> https://github.com/cocorossello/tomee-example
>
>
>
>
>
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680971.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Hi,

I'm running into problems with this, I think it might be another openejb
bug.

If I have two levels of EJB @async threads get stuck  at:

at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
    at java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at org.apache.openejb.threads.future.CUFuture.get(CUFuture.java:55)
    at
com.tr2.util.interceptor.async.FutureDelegator.get(FutureDelegator.java:19)

The setup is very simple
someStateless -> AsyncTask1 -> asyncTask2

I made an ApplicationComposer test (AsyncInterceptorIT) in that github
project (with latest SNAPSHOT)

https://github.com/cocorossello/tomee-example








--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680971.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Thank you!



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680946.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
fixed in https://issues.apache.org/jira/browse/TOMEE-2007


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-26 13:15 GMT+01:00 cocorossello <co...@gmail.com>:

> I couldn't get the attachment to work , I made a github project
>
> https://github.com/cocorossello/tomee-example
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680943.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
I couldn't get the attachment to work , I made a github project 

https://github.com/cocorossello/tomee-example



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680943.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Hi,

I think it is something related with tomee. I made a very simple webapp
showing the error, just the interceptor and 1 async method.

Can you please try it?

mvn clean install tomee:start
and go to http://localhost:8080/index.xhtml and reload 2 or  3 times, the
error should happen

Sorry, I couldn't get it working in applicationComposer



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680942.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
means an EJB is being setup while this same EJB is being copied in the
interceptor which is quite weird.

Side note: while your FutureDelegator is not wrapping the runnable/callable
submitted you will not get the MDB propagation working I think


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-26 11:44 GMT+01:00 cocorossello <co...@gmail.com>:

> I'm not using EjbContext at all. It isn't MDC problem as well, I don't
> really
> know what's going on, the inerceptor is fairly simple.
>
>
>     @AroundInvoke
>     public Object submitAsync(InvocationContext ctx) throws Exception {
>         if (executor == null) {
>             executor = (ManagedExecutorService) new
> InitialContext().lookup("openejb:Resource/TravelcAsynchronousPool");
>         }
>         Future resultFuture = new FutureDelegator(executor.submit(() -> {
>             return ctx.proceed();
>         }));
>         if (ctx.getMethod().getReturnType() == Void.TYPE) {
>             return null;
>         }
>
>         return resultFuture;
>     }
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680940.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
I'm not using EjbContext at all. It isn't MDC problem as well, I don't really
know what's going on, the inerceptor is fairly simple.


    @AroundInvoke
    public Object submitAsync(InvocationContext ctx) throws Exception {
        if (executor == null) {
            executor = (ManagedExecutorService) new
InitialContext().lookup("openejb:Resource/TravelcAsynchronousPool");
        }
        Future resultFuture = new FutureDelegator(executor.submit(() -> {
            return ctx.proceed();
        }));
        if (ctx.getMethod().getReturnType() == Void.TYPE) {
            return null;
        }

        return resultFuture;
    }



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680940.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi

no, the executor is really a singleton, this is fine. Looks more like you
reuse some EJB context in 2 places through the submit where it shouldn't.


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-26 11:10 GMT+01:00 cocorossello <co...@gmail.com>:

> Since I deployed the interceptor I can see some random errors happening in
> different points:
>
> java.util.ConcurrentModificationException: null
>         at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
>         at java.util.HashMap$EntryIterator.next(HashMap.java:1471)
>         at java.util.HashMap$EntryIterator.next(HashMap.java:1469)
>         at java.util.HashMap.putMapEntries(HashMap.java:511)
>         at java.util.HashMap.putAll(HashMap.java:784)
>         at java.util.Collections$SynchronizedMap.putAll(
> Collections.java:2594)
>         at org.apache.openejb.core.ThreadContext.<init>(
> ThreadContext.java:143)
>         at org.apache.openejb.threads.task.CUTask$Context.enter(
> CUTask.java:185)
>         at org.apache.openejb.threads.task.CUTask.invoke(CUTask.java:75)
>         at org.apache.openejb.threads.task.CUCallable.call(
> CUCallable.java:31)
>         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
>         at
> java.util.concurrent.ThreadPoolExecutor.runWorker(
> ThreadPoolExecutor.java:1142)
>         at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(
> ThreadPoolExecutor.java:617)
>         at java.lang.Thread.run(Thread.java:745)
>
> Could it be related to that I'm caching the executor and I shouldn't?
>
>         if (executor == null) {
>             executor = (ManagedExecutorService) new
> InitialContext().lookup("openejb:Resource/TravelcAsynchronousPool");
>         }
>
>
>
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680937.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Tomee 7.0.1 BTW , we didn't upgrade to 7.0.2



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680938.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
Since I deployed the interceptor I can see some random errors happening in
different points:

java.util.ConcurrentModificationException: null
	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
	at java.util.HashMap$EntryIterator.next(HashMap.java:1471)
	at java.util.HashMap$EntryIterator.next(HashMap.java:1469)
	at java.util.HashMap.putMapEntries(HashMap.java:511)
	at java.util.HashMap.putAll(HashMap.java:784)
	at java.util.Collections$SynchronizedMap.putAll(Collections.java:2594)
	at org.apache.openejb.core.ThreadContext.<init>(ThreadContext.java:143)
	at org.apache.openejb.threads.task.CUTask$Context.enter(CUTask.java:185)
	at org.apache.openejb.threads.task.CUTask.invoke(CUTask.java:75)
	at org.apache.openejb.threads.task.CUCallable.call(CUCallable.java:31)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

Could it be related to that I'm caching the executor and I shouldn't?

        if (executor == null) { 
            executor = (ManagedExecutorService) new
InitialContext().lookup("openejb:Resource/TravelcAsynchronousPool"); 
        } 






--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680937.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
I finally went without the managedTask, simpler (I couldn't get the resource
inyection, I don't know why, with priority and declaring it in beans.xml)

@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@Inherited
public @interface Async {

}



@Async
@Interceptor
public class AsyncInterceptor implements Serializable {

    private ManagedExecutorService executor;

    @AroundInvoke
    public Object submitAsync(InvocationContext ctx) throws Exception {
        if (executor == null) {
            executor = (ManagedExecutorService) new
InitialContext().lookup("openejb:Resource/TravelcAsynchronousPool");
        }
        Map<String, String> m = MDC.getCopyOfContextMap();
        FutureDelegator delegator = new FutureDelegator(executor.submit(()
-> {
            MDC.setContextMap(m);
            return ctx.proceed();
        }));
        return delegator;
    }
}




public class FutureDelegator implements Future {

    private final Future<?> future;

    public FutureDelegator(Future<?> future) {
        this.future = future;
    }

    @Override
    public Object get() throws InterruptedException, ExecutionException {
        AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
        if (asyncResult == null) {
            return null;
        }

        return asyncResult.get();
    }

    @Override
    public Object get(long timeout, TimeUnit unit) throws
InterruptedException, ExecutionException, TimeoutException {
        AsyncResult<?> asyncResult = (AsyncResult<?>) future.get(timeout,
unit);
        if (asyncResult == null) {
            return null;
        }

        return asyncResult.get();
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return future.cancel(mayInterruptIfRunning);
    }

    @Override
    public boolean isCancelled() {
        return future.isCancelled();
    }

    @Override
    public boolean isDone() {
        return future.isDone();
    }

}


Thanks Romain




--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680936.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
add @Priority on it or declare it in beans.Xml


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-25 13:59 GMT+01:00 cocorossello <co...@gmail.com>:

> It's not, my bad. The interceptor was not being applied and I thought it
> was OK.
>
> The problem I have now is that the excutor is not being inyected.
>
>     @Resource(name = "TravelcAsynchronousPool")
>     private ManagedExecutorService executor;
>
>
> And it is declared in resources.xml
>
>
>     <Resource id="TravelcAsynchronousPool" type="ManagedExecutorService">
>         Core 100
>         Max 200
>         Queue 1500
>         KeepAlive 1 s
>         ThreadFactory
> org.apache.openejb.threads.impl.ManagedThreadFactoryImpl
>         Lazy true
>     </Resource>
>
>
>
> On Wed, Jan 25, 2017 at 1:53 PM, Romain Manni-Bucau [via TomEE & OpenEJB] <
> ml-node+s979440n4680932h19@n4.nabble.com> wrote:
>
> > Does it work? shouldn't it be:
> >
> >     @AroundInvoke
> >     public Object submitAsync(InvocationContext ctx) throws Exception {
> >         return executor.submit(new FutureDelegator(() -> { // in the
> > constructor capture current MDC and (re)set it ManagedTaskListener hooks
> >             return ctx.proceed();
> >         }));
> >     }
> >
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://blog-rmannibucau.rhcloud.com> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <https://github.com/
> > rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
> > <https://javaeefactory-rmannibucau.rhcloud.com>
> >
> > 2017-01-25 13:24 GMT+01:00 cocorossello <[hidden email]
> > <http:///user/SendEmail.jtp?type=node&node=4680932&i=0>>:
> >
> > > I got it, this is the code just in case anyone needs it.
> > >
> > >
> > > @InterceptorBinding
> > > @Target({TYPE, METHOD})
> > > @Retention(RUNTIME)
> > > @Inherited
> > > public @interface Async {
> > >
> > > }
> > >
> > >
> > >
> > > @Async
> > > @Interceptor
> > > public class AsyncInterceptor implements Serializable {
> > >
> > >     @Resource(name = "TravelcAsynchronousPool")
> > >     private ManagedExecutorService executor;
> > >
> > >     @AroundInvoke
> > >     public Object submitAsync(InvocationContext ctx) throws Exception {
> > >         return new FutureDelegator(executor.submit(() -> {
> > >             return ctx.proceed();
> > >         }));
> > >     }
> > > }
> > >
> > >
> > >
> > >
> > >
> > >
> > > public class FutureDelegator implements Future, ManagedTask,
> > > ManagedTaskListener {
> > >
> > >     private final Future<?> future;
> > >     private Map<String, String> mdcCopy;
> > >
> > >     public FutureDelegator(Future<?> future) {
> > >         this.future = future;
> > >     }
> > >
> > >     @Override
> > >     public Object get() throws InterruptedException, ExecutionException
> > {
> > >         AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
> > >         if (asyncResult == null) {
> > >             return null;
> > >         }
> > >
> > >         return asyncResult.get();
> > >     }
> > >
> > >     @Override
> > >     public Object get(long timeout, TimeUnit unit) throws
> > > InterruptedException, ExecutionException, TimeoutException {
> > >         AsyncResult<?> asyncResult = (AsyncResult<?>)
> > future.get(timeout,
> > > unit);
> > >         if (asyncResult == null) {
> > >             return null;
> > >         }
> > >
> > >         return asyncResult.get();
> > >     }
> > >
> > >     @Override
> > >     public boolean cancel(boolean mayInterruptIfRunning) {
> > >         return future.cancel(mayInterruptIfRunning);
> > >     }
> > >
> > >     @Override
> > >     public boolean isCancelled() {
> > >         return future.isCancelled();
> > >     }
> > >
> > >     @Override
> > >     public boolean isDone() {
> > >         return future.isDone();
> > >     }
> > >
> > >     @Override
> > >     public ManagedTaskListener getManagedTaskListener() {
> > >         return this;
> > >     }
> > >
> > >     @Override
> > >     public Map<String, String> getExecutionProperties() {
> > >         return new HashMap();
> > >     }
> > >
> > >     @Override
> > >     public void taskSubmitted(Future<?> future, ManagedExecutorService
> > > executor, Object task) {
> > >         mdcCopy = MDC.getCopyOfContextMap();
> > >     }
> > >
> > >     @Override
> > >     public void taskAborted(Future<?> future, ManagedExecutorService
> > > executor, Object task, Throwable exception) {
> > >         //NADA
> > >     }
> > >
> > >     @Override
> > >     public void taskDone(Future<?> future, ManagedExecutorService
> > executor,
> > > Object task, Throwable exception) {
> > >         //NADA
> > >     }
> > >
> > >     @Override
> > >     public void taskStarting(Future<?> future, ManagedExecutorService
> > > executor, Object task) {
> > >         MDC.setContextMap(mdcCopy);
> > >     }
> > > }
> > >
> > >
> > >
> > >
> > > --
> > > View this message in context: http://tomee-openejb.979440.
> > > n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680931.html
> > > Sent from the TomEE Users mailing list archive at Nabble.com.
> > >
> >
> >
> > ------------------------------
> > If you reply to this email, your message will be added to the discussion
> > below:
> > http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-
> > tp4680927p4680932.html
> > To unsubscribe from MDC and @Asynchronous, click here
> > <http://tomee-openejb.979440.n4.nabble.com/template/
> NamlServlet.jtp?macro=unsubscribe_by_code&node=4680927&code=
> Y29jb3Jvc3NlbGxvQGdtYWlsLmNvbXw0NjgwOTI3fC05Mzc2MzQ4MzY=>
> > .
> > NAML
> > <http://tomee-openejb.979440.n4.nabble.com/template/
> NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
> >
>
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680933.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
It's not, my bad. The interceptor was not being applied and I thought it
was OK.

The problem I have now is that the excutor is not being inyected.

    @Resource(name = "TravelcAsynchronousPool")
    private ManagedExecutorService executor;


And it is declared in resources.xml


    <Resource id="TravelcAsynchronousPool" type="ManagedExecutorService">
        Core 100
        Max 200
        Queue 1500
        KeepAlive 1 s
        ThreadFactory
org.apache.openejb.threads.impl.ManagedThreadFactoryImpl
        Lazy true
    </Resource>



On Wed, Jan 25, 2017 at 1:53 PM, Romain Manni-Bucau [via TomEE & OpenEJB] <
ml-node+s979440n4680932h19@n4.nabble.com> wrote:

> Does it work? shouldn't it be:
>
>     @AroundInvoke
>     public Object submitAsync(InvocationContext ctx) throws Exception {
>         return executor.submit(new FutureDelegator(() -> { // in the
> constructor capture current MDC and (re)set it ManagedTaskListener hooks
>             return ctx.proceed();
>         }));
>     }
>
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://blog-rmannibucau.rhcloud.com> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/
> rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
> <https://javaeefactory-rmannibucau.rhcloud.com>
>
> 2017-01-25 13:24 GMT+01:00 cocorossello <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4680932&i=0>>:
>
> > I got it, this is the code just in case anyone needs it.
> >
> >
> > @InterceptorBinding
> > @Target({TYPE, METHOD})
> > @Retention(RUNTIME)
> > @Inherited
> > public @interface Async {
> >
> > }
> >
> >
> >
> > @Async
> > @Interceptor
> > public class AsyncInterceptor implements Serializable {
> >
> >     @Resource(name = "TravelcAsynchronousPool")
> >     private ManagedExecutorService executor;
> >
> >     @AroundInvoke
> >     public Object submitAsync(InvocationContext ctx) throws Exception {
> >         return new FutureDelegator(executor.submit(() -> {
> >             return ctx.proceed();
> >         }));
> >     }
> > }
> >
> >
> >
> >
> >
> >
> > public class FutureDelegator implements Future, ManagedTask,
> > ManagedTaskListener {
> >
> >     private final Future<?> future;
> >     private Map<String, String> mdcCopy;
> >
> >     public FutureDelegator(Future<?> future) {
> >         this.future = future;
> >     }
> >
> >     @Override
> >     public Object get() throws InterruptedException, ExecutionException
> {
> >         AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
> >         if (asyncResult == null) {
> >             return null;
> >         }
> >
> >         return asyncResult.get();
> >     }
> >
> >     @Override
> >     public Object get(long timeout, TimeUnit unit) throws
> > InterruptedException, ExecutionException, TimeoutException {
> >         AsyncResult<?> asyncResult = (AsyncResult<?>)
> future.get(timeout,
> > unit);
> >         if (asyncResult == null) {
> >             return null;
> >         }
> >
> >         return asyncResult.get();
> >     }
> >
> >     @Override
> >     public boolean cancel(boolean mayInterruptIfRunning) {
> >         return future.cancel(mayInterruptIfRunning);
> >     }
> >
> >     @Override
> >     public boolean isCancelled() {
> >         return future.isCancelled();
> >     }
> >
> >     @Override
> >     public boolean isDone() {
> >         return future.isDone();
> >     }
> >
> >     @Override
> >     public ManagedTaskListener getManagedTaskListener() {
> >         return this;
> >     }
> >
> >     @Override
> >     public Map<String, String> getExecutionProperties() {
> >         return new HashMap();
> >     }
> >
> >     @Override
> >     public void taskSubmitted(Future<?> future, ManagedExecutorService
> > executor, Object task) {
> >         mdcCopy = MDC.getCopyOfContextMap();
> >     }
> >
> >     @Override
> >     public void taskAborted(Future<?> future, ManagedExecutorService
> > executor, Object task, Throwable exception) {
> >         //NADA
> >     }
> >
> >     @Override
> >     public void taskDone(Future<?> future, ManagedExecutorService
> executor,
> > Object task, Throwable exception) {
> >         //NADA
> >     }
> >
> >     @Override
> >     public void taskStarting(Future<?> future, ManagedExecutorService
> > executor, Object task) {
> >         MDC.setContextMap(mdcCopy);
> >     }
> > }
> >
> >
> >
> >
> > --
> > View this message in context: http://tomee-openejb.979440.
> > n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680931.html
> > Sent from the TomEE Users mailing list archive at Nabble.com.
> >
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
> http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-
> tp4680927p4680932.html
> To unsubscribe from MDC and @Asynchronous, click here
> <http://tomee-openejb.979440.n4.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=4680927&code=Y29jb3Jvc3NlbGxvQGdtYWlsLmNvbXw0NjgwOTI3fC05Mzc2MzQ4MzY=>
> .
> NAML
> <http://tomee-openejb.979440.n4.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>




--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680933.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Does it work? shouldn't it be:

    @AroundInvoke
    public Object submitAsync(InvocationContext ctx) throws Exception {
        return executor.submit(new FutureDelegator(() -> { // in the
constructor capture current MDC and (re)set it ManagedTaskListener hooks
            return ctx.proceed();
        }));
    }


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-25 13:24 GMT+01:00 cocorossello <co...@gmail.com>:

> I got it, this is the code just in case anyone needs it.
>
>
> @InterceptorBinding
> @Target({TYPE, METHOD})
> @Retention(RUNTIME)
> @Inherited
> public @interface Async {
>
> }
>
>
>
> @Async
> @Interceptor
> public class AsyncInterceptor implements Serializable {
>
>     @Resource(name = "TravelcAsynchronousPool")
>     private ManagedExecutorService executor;
>
>     @AroundInvoke
>     public Object submitAsync(InvocationContext ctx) throws Exception {
>         return new FutureDelegator(executor.submit(() -> {
>             return ctx.proceed();
>         }));
>     }
> }
>
>
>
>
>
>
> public class FutureDelegator implements Future, ManagedTask,
> ManagedTaskListener {
>
>     private final Future<?> future;
>     private Map<String, String> mdcCopy;
>
>     public FutureDelegator(Future<?> future) {
>         this.future = future;
>     }
>
>     @Override
>     public Object get() throws InterruptedException, ExecutionException {
>         AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
>         if (asyncResult == null) {
>             return null;
>         }
>
>         return asyncResult.get();
>     }
>
>     @Override
>     public Object get(long timeout, TimeUnit unit) throws
> InterruptedException, ExecutionException, TimeoutException {
>         AsyncResult<?> asyncResult = (AsyncResult<?>) future.get(timeout,
> unit);
>         if (asyncResult == null) {
>             return null;
>         }
>
>         return asyncResult.get();
>     }
>
>     @Override
>     public boolean cancel(boolean mayInterruptIfRunning) {
>         return future.cancel(mayInterruptIfRunning);
>     }
>
>     @Override
>     public boolean isCancelled() {
>         return future.isCancelled();
>     }
>
>     @Override
>     public boolean isDone() {
>         return future.isDone();
>     }
>
>     @Override
>     public ManagedTaskListener getManagedTaskListener() {
>         return this;
>     }
>
>     @Override
>     public Map<String, String> getExecutionProperties() {
>         return new HashMap();
>     }
>
>     @Override
>     public void taskSubmitted(Future<?> future, ManagedExecutorService
> executor, Object task) {
>         mdcCopy = MDC.getCopyOfContextMap();
>     }
>
>     @Override
>     public void taskAborted(Future<?> future, ManagedExecutorService
> executor, Object task, Throwable exception) {
>         //NADA
>     }
>
>     @Override
>     public void taskDone(Future<?> future, ManagedExecutorService executor,
> Object task, Throwable exception) {
>         //NADA
>     }
>
>     @Override
>     public void taskStarting(Future<?> future, ManagedExecutorService
> executor, Object task) {
>         MDC.setContextMap(mdcCopy);
>     }
> }
>
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680931.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
I got it, this is the code just in case anyone needs it.


@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@Inherited
public @interface Async {

}



@Async
@Interceptor
public class AsyncInterceptor implements Serializable {

    @Resource(name = "TravelcAsynchronousPool")
    private ManagedExecutorService executor;

    @AroundInvoke
    public Object submitAsync(InvocationContext ctx) throws Exception {
        return new FutureDelegator(executor.submit(() -> {
            return ctx.proceed();
        }));
    }
}






public class FutureDelegator implements Future, ManagedTask,
ManagedTaskListener {

    private final Future<?> future;
    private Map<String, String> mdcCopy;

    public FutureDelegator(Future<?> future) {
        this.future = future;
    }

    @Override
    public Object get() throws InterruptedException, ExecutionException {
        AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
        if (asyncResult == null) {
            return null;
        }

        return asyncResult.get();
    }

    @Override
    public Object get(long timeout, TimeUnit unit) throws
InterruptedException, ExecutionException, TimeoutException {
        AsyncResult<?> asyncResult = (AsyncResult<?>) future.get(timeout,
unit);
        if (asyncResult == null) {
            return null;
        }

        return asyncResult.get();
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return future.cancel(mayInterruptIfRunning);
    }

    @Override
    public boolean isCancelled() {
        return future.isCancelled();
    }

    @Override
    public boolean isDone() {
        return future.isDone();
    }

    @Override
    public ManagedTaskListener getManagedTaskListener() {
        return this;
    }

    @Override
    public Map<String, String> getExecutionProperties() {
        return new HashMap();
    }

    @Override
    public void taskSubmitted(Future<?> future, ManagedExecutorService
executor, Object task) {
        mdcCopy = MDC.getCopyOfContextMap();
    }

    @Override
    public void taskAborted(Future<?> future, ManagedExecutorService
executor, Object task, Throwable exception) {
        //NADA
    }

    @Override
    public void taskDone(Future<?> future, ManagedExecutorService executor,
Object task, Throwable exception) {
        //NADA
    }

    @Override
    public void taskStarting(Future<?> future, ManagedExecutorService
executor, Object task) {
        MDC.setContextMap(mdcCopy);
    }
}




--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680931.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by cocorossello <co...@gmail.com>.
I'll go that way, thank you very much.

If you have that sample it would be very useful. I'm trying to build my own
but it's not trivial (for me)



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/MDC-and-Asynchronous-tp4680927p4680930.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: MDC and @Asynchronous

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hello

with @Asynchronous it can be tricky and highly container dependent but if
you migrate to ManagedExecutor service (it is quite trivial to do a cdi
interceptor implementing @Async to make it smoother) then you can submit
ManagedTask which can have task listener which would allow when creating
the task to submit the current MDC and propagate it

Should still have a sample doing it if you need help going that way


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

2017-01-25 11:56 GMT+01:00 cocorossello <co...@gmail.com>:

> Hi,
>
> I'm using logback's MDC to setup some logging info accross my application
> (jsessionid and other stuff). Our application uses lots of @Asynchronous
> methods. Since logback 1.1.3 MDC context is not propagated to child
> threads.
>
> Is there any way to customise the asynchronous thread pool executor so I
> can
> propagate manually the context as logback docs says?
>
> /MDC And Managed Threads
>
> A copy of the mapped diagnostic context can not always be inherited by
> worker threads from the initiating thread. This is the case when
> java.util.concurrent.Executors is used for thread management. For instance,
> newCachedThreadPool method creates a ThreadPoolExecutor and like other
> thread pooling code, it has intricate thread creation logic.
>
> In such cases, it is recommended that MDC.getCopyOfContextMap() is invoked
> on the original (master) thread before submitting a task to the executor.
> When the task runs, as its first action, it should invoke
> MDC.setContextMapValues() to associate the stored copy of the original MDC
> values with the new Executor managed thread./
>
> (or should I just forget MDC and think of another "context" mechanism?)
>
>
>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/MDC-and-Asynchronous-tp4680927.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>