Typically what you would do is store the object you want to propagate in an
Exchange property, eg. just before a threads() DSL.

On the other side of the concurrency threshold, you would unwrap the object
back into its thread-bound structure from the Exchange property.

If you have a look at the feature/camel-hystrix branch, I'm implementing
something similar to propagate the HystrixRequestContext, which is
otherwise thread-bound.

Raúl.
On 27 Aug 2015 21:16, "Jan Zankowski" <[email protected]> wrote:

> 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 <[email protected]
> >
> 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 <[email protected]>:
> >
> > > 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 <
> [email protected]
> > >
> > > 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
> > > >
> > >
> >
>

Reply via email to