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