Quantcast

[scala] Thread Local context made easy with Scala

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Thread Local context made easy with Scala

Erkki Lindpere-2
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.

trait RenderContext {
  // interface skipped
}
object RenderContext extends ThreadLocal[RenderContext]

That's it, now we can use it like this:

  RenderContext.set(new RenderContext {
    // impl skipped
  })
  try {
    // do stuff with context present
  } finally {
    RenderContext.remove
  }

Has anyone else used threadlocals in Scala similarly?

Erkki
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Sean McDirmid
See scala.util.DynamicVariable

Sean

On Sat, Aug 2, 2008 at 10:19 PM, Erkki Lindpere <[hidden email]> wrote:
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.

trait RenderContext {
 // interface skipped
}
object RenderContext extends ThreadLocal[RenderContext]

That's it, now we can use it like this:

 RenderContext.set(new RenderContext {
  // impl skipped
 })
 try {
  // do stuff with context present
 } finally {
  RenderContext.remove
 }

Has anyone else used threadlocals in Scala similarly?

Erkki

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Jamie Webb-2
In reply to this post by Erkki Lindpere-2
On 2008-08-02 17:19:26 Erkki Lindpere wrote:

> 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.
>
> trait RenderContext {
>   // interface skipped
> }
> object RenderContext extends ThreadLocal[RenderContext]
>
> That's it, now we can use it like this:
>
>   RenderContext.set(new RenderContext {
>     // impl skipped
>   })
>   try {
>     // do stuff with context present
>   } finally {
>     RenderContext.remove
>   }
>
> Has anyone else used threadlocals in Scala similarly?

You are better off using scala.util.DynamicVariable, specifically the
withValue method. This makes it much easier to be sure of correct
scoping.

See http://scala.sygneca.com/patterns/loan for an explanation of the
general pattern employed here. Also see
http://scala.sygneca.com/patterns/dynamic-scope for some alternative
approaches.

/J
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Erkki Lindpere-2
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).

Erkki

Jamie Webb wrote:

> On 2008-08-02 17:19:26 Erkki Lindpere wrote:
>  
>> 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.
>>
>> trait RenderContext {
>>   // interface skipped
>> }
>> object RenderContext extends ThreadLocal[RenderContext]
>>
>> That's it, now we can use it like this:
>>
>>   RenderContext.set(new RenderContext {
>>     // impl skipped
>>   })
>>   try {
>>     // do stuff with context present
>>   } finally {
>>     RenderContext.remove
>>   }
>>
>> Has anyone else used threadlocals in Scala similarly?
>>    
>
> You are better off using scala.util.DynamicVariable, specifically the
> withValue method. This makes it much easier to be sure of correct
> scoping.
>
> See http://scala.sygneca.com/patterns/loan for an explanation of the
> general pattern employed here. Also see
> http://scala.sygneca.com/patterns/dynamic-scope for some alternative
> approaches.
>
> /J
>
>  
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

David MacIver
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Sean McDirmid
In reply to this post by Jamie Webb-2
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....).

On Sat, Aug 2, 2008 at 10:33 PM, Jamie Webb <[hidden email]> wrote:
On 2008-08-02 17:19:26 Erkki Lindpere wrote:
> 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.
>
> trait RenderContext {
>   // interface skipped
> }
> object RenderContext extends ThreadLocal[RenderContext]
>
> That's it, now we can use it like this:
>
>   RenderContext.set(new RenderContext {
>     // impl skipped
>   })
>   try {
>     // do stuff with context present
>   } finally {
>     RenderContext.remove
>   }
>
> Has anyone else used threadlocals in Scala similarly?

You are better off using scala.util.DynamicVariable, specifically the
withValue method. This makes it much easier to be sure of correct
scoping.

See http://scala.sygneca.com/patterns/loan for an explanation of the
general pattern employed here. Also see
http://scala.sygneca.com/patterns/dynamic-scope for some alternative
approaches.

/J

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Jamie Webb-2
In reply to this post by David MacIver
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
and b) the device that would support them looks exactly like a
DynamicVariable but uses a vanilla ThreadLocal.

/J
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

David Pollak
In reply to this post by Erkki Lindpere-2
Erkki,

Yes, lift (http://liftweb.net ) makes extensive use of thread locals.  
The "S" (short for Stateful) object contains all the state for the
current request.

Thanks,

David

Erkki Lindpere wrote:

> 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.
>
> trait RenderContext {
>  // interface skipped
> }
> object RenderContext extends ThreadLocal[RenderContext]
>
> That's it, now we can use it like this:
>
>  RenderContext.set(new RenderContext {
>    // impl skipped
>  })
>  try {
>    // do stuff with context present
>  } finally {
>    RenderContext.remove
>  }
>
> Has anyone else used threadlocals in Scala similarly?
>
> Erkki

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

David MacIver
In reply to this post by Jamie Webb-2
On Sat, Aug 2, 2008 at 4:35 PM, Jamie Webb <[hidden email]> wrote:

> 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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Jorge Ortiz
In reply to this post by David Pollak
Erikki, check out net.liftweb.util.ThreadGlobal for lift's version of
DynamicVariable that uses vanilla (non-Inheritable) ThreadLocals.

--j

On Sat, Aug 2, 2008 at 8:38 AM, David Pollak <[hidden email]> wrote:

> Erkki,
>
> Yes, lift (http://liftweb.net ) makes extensive use of thread locals.  The
> "S" (short for Stateful) object contains all the state for the current
> request.
>
> Thanks,
>
> David
>
> Erkki Lindpere wrote:
>>
>> 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.
>>
>> trait RenderContext {
>>  // interface skipped
>> }
>> object RenderContext extends ThreadLocal[RenderContext]
>>
>> That's it, now we can use it like this:
>>
>>  RenderContext.set(new RenderContext {
>>   // impl skipped
>>  })
>>  try {
>>   // do stuff with context present
>>  } finally {
>>   RenderContext.remove
>>  }
>>
>> Has anyone else used threadlocals in Scala similarly?
>>
>> Erkki
>
>
Loading...