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 > > > > > > > > > >
