[scala] Thread Local context made easy with Scala

[scala] Thread Local context made easy with Scala

I just noticed that besides the singleton pattern made really easy in
Scala, it's also very easy to define ThreadLocals that in Java would be
accessed statically or through a singleton. Several Java frameworks (for
example Spring, Struts, Hibernate) sometimes use thread locals (with a
singleton or static holder class to access it) for various kinds of
temporary contextual information, such as connections, transactions, web
request, security etc. As I understand, it is mostly done to avoid
making interfaces directly dependenent on such contexts by explicitly
passing them around. Implicits wouldn't help here either.

Seems really simple to do in Scala: instead of a custom simple wrapper
class with static methods, we can declare an even simpler companion
object for our context type, extending ThreadLocal[ContextType]. Then we
just use the get, set and remove methods as necessary on the companion
object.

Re: [scala] Thread Local context made easy with Scala

I just noticed that besides the singleton pattern made really easy in Scala, it's also very easy to define ThreadLocals that in Java would be accessed statically or through a singleton. Several Java frameworks (for example Spring, Struts, Hibernate) sometimes use thread locals (with a singleton or static holder class to access it) for various kinds of temporary contextual information, such as connections, transactions, web request, security etc. As I understand, it is mostly done to avoid making interfaces directly dependenent on such contexts by explicitly passing them around. Implicits wouldn't help here either.

Seems really simple to do in Scala: instead of a custom simple wrapper class with static methods, we can declare an even simpler companion object for our context type, extending ThreadLocal[ContextType]. Then we just use the get, set and remove methods as necessary on the companion object.

Re: [scala] Thread Local context made easy with Scala

On Sat, Aug 2, 2008 at 3:52 PM, Erkki Lindpere <[hidden email]> wrote:
> Thanks for the suggestion. I actually new about DynamicVariable, but it uses
> InheritableThreadLocal. I'm not sure I want that, although in my current
> usage it probably doesn't make a difference.
>
> Actually it would probably be nice if DynamicVariable would allow choosing
> between inheritable and simple threadlocals (via boolean argument or maybe a
> subclass or mixin).

I hear this a lot, but without any very convincing arguments for it. I
remain convinced that using an InheritableThreadLocal is the only
semantically correct way for DynamicVariable to work given its
intended scoping semantics.

In particular:

myDynamicVariable.withValue(value){
// myDynamicVariable should have the specified value in here
}

Even in cases like the following:

myDynamicVariable.withValue(value){
spawn{
// do stuff in another thread
}
}

There are of course plenty of use cases for non-inheritable
threadlocals. I just don't think dynamic variables are one of them.

Re: [scala] Thread Local context made easy with Scala

The wiki entries are a bit misleading on dynamic scope. There are inherit limitations in FP that often make dynamic scope necessary or at least preferrable. The best use case for dynamic scope is tunneling through some fixed APIs; e.g., having some method called indirectly by foreach method use some context that is specified by the caller of the foreach method. In this case, we can't change foreach to have a context parameter, so we use dynamic scope instead. Another use case is simply redirecting output (which I think is what drove Lex to write this code in the first place) or otherwise re-configuring how code interacts with an otherwise static environment.

For this reason, dynamic scope is present in the functional languages I know (e.g., fluid-let in Sceme, while in Haskell this could somehow be done through a monad) and has very clear use cases. It was accidentally chosen as the scoping mechanism in the first LISP implementation, but this was more due to a misunderstanding, I think (the stories PL professors tell....).

Re: [scala] Thread Local context made easy with Scala

> On Sat, Aug 2, 2008 at 3:52 PM, Erkki Lindpere <[hidden email]> wrote:
> > Thanks for the suggestion. I actually new about DynamicVariable,
> > but it uses InheritableThreadLocal. I'm not sure I want that,
> > although in my current usage it probably doesn't make a difference.
> >
> > Actually it would probably be nice if DynamicVariable would allow
> > choosing between inheritable and simple threadlocals (via boolean
> > argument or maybe a subclass or mixin).
>
> I hear this a lot, but without any very convincing arguments for it. I
> remain convinced that using an InheritableThreadLocal is the only
> semantically correct way for DynamicVariable to work given its
> intended scoping semantics.

InheritableThreadLocal is correct for immutable, thread-safe context.
It's completely wrong for anything with a state or lifecycle, for
hopefully obvious reasons. For example, many frameworks put the active
database connection in a ThreadLocal. That's a seemingly-obvious usage
for DynamicVariable, but it would be quite broken.

So, feel free to claim these uses are not intended to be supported by
DynamicVariable, but that will not change the fact that a) they exist
and b) the device that would support them looks exactly like a
DynamicVariable but uses a vanilla ThreadLocal.

Re: [scala] Thread Local context made easy with Scala

> On 2008-08-02 15:56:47 David MacIver wrote:
>> On Sat, Aug 2, 2008 at 3:52 PM, Erkki Lindpere <[hidden email]> wrote:
>> > Thanks for the suggestion. I actually new about DynamicVariable,
>> > but it uses InheritableThreadLocal. I'm not sure I want that,
>> > although in my current usage it probably doesn't make a difference.
>> >
>> > Actually it would probably be nice if DynamicVariable would allow
>> > choosing between inheritable and simple threadlocals (via boolean
>> > argument or maybe a subclass or mixin).
>>
>> I hear this a lot, but without any very convincing arguments for it. I
>> remain convinced that using an InheritableThreadLocal is the only
>> semantically correct way for DynamicVariable to work given its
>> intended scoping semantics.
>
> InheritableThreadLocal is correct for immutable, thread-safe context.
> It's completely wrong for anything with a state or lifecycle, for
> hopefully obvious reasons. For example, many frameworks put the active
> database connection in a ThreadLocal. That's a seemingly-obvious usage
> for DynamicVariable, but it would be quite broken.
>
> So, feel free to claim these uses are not intended to be supported by
> DynamicVariable, but that will not change the fact that a) they exist

Then perhaps there should be a common interface and an alternative
implementation which uses a normal thread local. If you want one, it
would take all of 10 minutes to write. But what you're describing is
not a dynamically scoped variable.

> and b) the device that would support them looks exactly like a
> DynamicVariable but uses a vanilla ThreadLocal.

It might look exactly like one, but it wouldn't support the intended contract.