camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jan Zankowski <jan.zankow...@gmail.com>
Subject Is it safe to use ThreadLocal<Exchange> to implement route scope for dependency injection?
Date Mon, 24 Aug 2015 10:47:48 GMT
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