camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jan Zankowski <jan.zankow...@gmail.com>
Subject Re: Is it safe to use ThreadLocal<Exchange> to implement route scope for dependency injection?
Date Thu, 27 Aug 2015 20:16:21 GMT
Right - I just found your code. The limitation you mention - async
processors, threads(), multicast() - is exactly what the approach I
describe is meant to overcome.

When a situation like that happens, i.e. a new thread takes over, it gets a
copy of the original exchange, and an ExchangeCreateEvent is fired in it,
allowing a listener to set the copy of exchange on the new thread's
ThreadLocal. This should provide continuity of route scope.

This is what the author of the code I point to claims, and it seems to
work. My main question is: is this guaranteed to work? I.e., if adjacent
components A and B on the same route are executed by different threads, can
I always be sure that the new thread (or threads) executing B will each
copy the exchange and fire ExchangeCreatedEvent before executing B?

On Thu, Aug 27, 2015 at 8:19 PM, Romain Manni-Bucau <rmannibucau@gmail.com>
wrote:

> this is what I used to implement an @ExchangeScoped but it has several
> limitation, in particular when breaking the flow with .threads() or
> .multicast(). All is explained on
> http://camel.apache.org/threading-model.html .
>
> Using a camel interceptor would surely allow to pass the context through
> the exchange and therefor avoid this ThreadLocal but this needs few more
> setup and is less "magic".
>
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Tomitriber
> <http://www.tomitribe.com>
>
> 2015-08-27 20:13 GMT+02:00 Jan Zankowski <jan.zankowski@gmail.com>:
>
> > Just wanted to ping the thread in the hope someone will offer help.. I
> > think the answer may also be useful to people in other situations who
> > wonder how Camel works under the hood with regard to threads. Thanks!
> >
> > On Mon, Aug 24, 2015 at 12:47 PM, Jan Zankowski <jan.zankowski@gmail.com
> >
> > wrote:
> >
> > > Hi,
> > >
> > > My goal is to implement DB multitenancy in a Camel application using
> > > Hibernate and Spring. For this, I need to implement the following
> > Hibernate
> > > interface, which gets called on each read/write to the DB.
> > >
> > > public interface CurrentTenantIdentifierResolver {
> > >   public String resolveCurrentTenantIdentifier();
> > >   [...]
> > > }
> > >
> > > Because the method doesn't take any parameters, it either needs to use
> > (1)
> > > some static context knowing which tenant the current route execution
> > > belongs to, or (2) a dependency-injected manager holding such a
> context.
> > >
> > > (1) points me to using ThreadLocal holding the current Exchange as it
> > > travels down the route. The Exchange can have some custom field
> > indicating
> > > the tenant.
> > > (2) requires using "route scope" - where each route execution gets its
> > own
> > > instance of context manager injected into
> > CurrentTenantIdentifierResolver.
> > > Implementing the route scope, however, seems to require the same as
> (1) -
> > > ThreadLocal referencing the Exchange.
> > >
> > > I found the following article (& Git repo) implementing "route scope"
> > > exactly in this way:
> > > https://blog.jyore.com/2015/01/spring-camel-route-bean-scoping/ It
> > claims
> > > to take advantage of the fact that if a new thread starts processing
> the
> > > Exchange as it travels down the route, for example after a
> > > parallel-processing multicast, the new thread gets a copy of the
> original
> > > Exchange, and an ExchangeCreatedEvent is fired, allowing a listener to
> > set
> > > the ThreadLocal on the new thread.
> > >
> > > I was able to get this to work, though clearing of the ThreadLocal on
> > > ExchangeCompletedEvent doesn't work as the author claims, because the
> > event
> > > is fired on a different thread (I checked).
> > >
> > > Such issues make me wonder if it's safe to use such a solution.
> > >
> > > I have the following questions in particular:
> > > (a) Let's assume an Exchange E is travelling down a route with a
> segment
> > > ... -> A -> B -> ... If A and B are executed by different threads,
is
> it
> > > guaranteed that the new thread (or threads) executing B will each copy
> > the
> > > exchange and fire ExchangeCreatedEvent before executing B?
> > > (b) Why is ExchangeCompletedEvent sent by a different thread than the
> one
> > > executing L, the last endpoint on the route? Can I use some other hook
> to
> > > clear the ThreadLocal on the thread executing L, after L is executed?
> > Maybe
> > > a custom RoutePolicy, custom SynchronizationAdapter, or onCompletion()?
> > > (c) Can Asynchronous Routing Engine or AsyncProcessors cause any
> problems
> > > in this setup? (If the answer to (a) is "yes", I'd assume they won't
> > cause
> > > problems.)
> > > (d) Any other caveats?
> > >
> > > This thread is related:
> > >
> >
> http://camel.465427.n5.nabble.com/Clearing-ThreadLocal-when-exchange-completes-td5729849.html
> > >
> > > Many thanks!
> > > Jan
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message