[Haskell] thread-local variables (was: Re: Implicit Parameters)

Einar Karttunen ekarttun at cs.helsinki.fi
Sun Jul 30 20:54:29 EDT 2006


On 30.07 11:49, Frederik Eaton wrote:
> No, because the thread in which it runs inherits any thread-local
> state from its parent.


So we have different threads modifying the thread-local state?
If it is a copy then updates are not propagated.

What about a design with 10 worker threads taking requests
from a "Chan (IO ())" and running them (this occurs in real code).
To get things right they should use the TLS-context relevant
to each "IO ()" rather than the thread.
 
> > Now if the action changes the thread local state then
> > it behaves differently. Do we really want that?
> 
> I'm not sure what you're suggesting. The API I proposed actually
> doesn't let users discover when their actions are running in
> sub-threads. (Can you write an example using that API?) However, even
> if it did, I don't see a problem. Do you think that we should get rid
> of 'myThreadId', for instance? I don't.

I do consider using myThreadId bad form for most purposes.
It is nice to have for debugging output - and occasionally
for sending other threads a handle for asynchronous exceptions,
but this can lead to problems when changing threading patterns.

Usually nice code does not care in which thread it is run.

 
> > Usually one can just add a monad that wraps IO/STM and provides the
> > variables one needs. This has the good side of making scoping
> > explicit.
> 
> That's easier said than done. Sometimes I take that route. But
> sometimes I don't want 5 different monads wrapping each other, each
> with its own 'lift' and 'catch' functions, making error messages
> indecipherable and code difficult to read and debug. Do you propose
> creating a special monad for file operations? For network operations? 
> No? Then I don't see why I should have to make a special monad for
> database operations. Or, if the answer was "yes", then fine: obfuscate
> your own code, but please don't ask me to do the same. Let's support
> both ways of doing things, and we can be different.

Usually I just define one custom monad for the application which
wraps the stack of monad transformers. Thus changing the monad stack
does not affect the application code. A quite clean and efficient
solution.

My main objection to the TLS is that it looks like normal IO,
but changing the thread that evaluates it can break things in ways
that are hard to debug. E.g. we have an application that uses
TLS and passes an IO action to a library that happens to use
a pool of worker threads that invisible to the application. 
Or the same with the role of the application and library reversed.

Offering it up as a separate library should be ok as it would
be very easy to spot and take extra care not to cause problems.

- Einar Karttunen


More information about the Haskell mailing list