
Folks, I'm launching thousands of threads that send and receive commands. I would like the launching thread to keep a log of all the commands sent and received, in proper order. This would mean that each time a command is sent and received in the child thread it would need to be sent back to parent who would log the command on a first-come first-serve basis. How would I implement this in Haskell? Thanks, Joel -- http://wagerlabs.com/

On 10/31/05, Joel Reymont
Folks,
I'm launching thousands of threads that send and receive commands. I would like the launching thread to keep a log of all the commands sent and received, in proper order.
This would mean that each time a command is sent and received in the child thread it would need to be sent back to parent who would log the command on a first-come first-serve basis.
How would I implement this in Haskell?
How about using a Chan? http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurren... Send the Chan to all of the forked off processesses (so they take a Chan as an argument). Whenever they need to send something back to the server they write it to the Chan. The main thread can then just read off the Chan and log it. /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

Or perhaps a TChan, if that is more appropriate: http://www.haskell.org/ghc/docs/latest/html/libraries/stm/Control-Concurrent... I like the curried command idiom: do chan <- newChan let logToParent = writeChan chan do tChan <- newTChan let logToParentSTM = writeTChan tChan let logToParent = atomically.logToParentSTM do mVar <- newEmptyMVar let logToParent = putMVar mVar logToParentSTM :: a -> STM a logToParent :: a -> IO a Then pass logToParent/STM to the child threads, which never need to know the details of how data is being passed back to the parent thread. Log to parent could do all kinds of book-keeping, logging, synchronizaion, etc, while keeping the same a->IO a type and without modifying the client. Sebastian Sylvan wrote:
On 10/31/05, Joel Reymont
wrote: Folks,
I'm launching thousands of threads that send and receive commands. I would like the launching thread to keep a log of all the commands sent and received, in proper order.
This would mean that each time a command is sent and received in the child thread it would need to be sent back to parent who would log the command on a first-come first-serve basis.
How would I implement this in Haskell?
How about using a Chan?
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurren...
Send the Chan to all of the forked off processesses (so they take a Chan as an argument). Whenever they need to send something back to the server they write it to the Chan. The main thread can then just read off the Chan and log it.
/S
-- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

So when should I use a STM TChan instead of a regular Chan? On Oct 31, 2005, at 10:08 PM, ChrisK wrote:
Or perhaps a TChan, if that is more appropriate:
http://www.haskell.org/ghc/docs/latest/html/libraries/stm/Control- Concurrent-STM-TChan.html
I like the curried command idiom:
I'm not sure I understand this. Are you trying to show that the same logToParent approach can be used with Chan, TChan and MVar below?
do chan <- newChan let logToParent = writeChan chan
do tChan <- newTChan let logToParentSTM = writeTChan tChan let logToParent = atomically.logToParentSTM
do mVar <- newEmptyMVar let logToParent = putMVar mVar
Thanks, Joel -- http://wagerlabs.com/

Joel Reymont wrote:
So when should I use a STM TChan instead of a regular Chan?
On Oct 31, 2005, at 10:08 PM, ChrisK wrote:
Or perhaps a TChan, if that is more appropriate:
http://www.haskell.org/ghc/docs/latest/html/libraries/stm/Control- Concurrent-STM-TChan.html
I like the curried command idiom:
I'm not sure I understand this. Are you trying to show that the same logToParent approach can be used with Chan, TChan and MVar below?
do chan <- newChan let logToParent = writeChan chan
do tChan <- newTChan let logToParentSTM = writeTChan tChan let logToParent = atomically.logToParentSTM
do mVar <- newEmptyMVar let logToParent = putMVar mVar
Thanks, Joel
Yes, exactly. I listed several alternatives. The logToParent approach hides the actualy mechanism in use. This has 2 advantages: * You can switch the code for logToParent without messing with the child code (or type signatures!) The Chan/TChan are non-blocking while the MVar (or TMVar) would block, so this is a non-trivial difference. * The child has no reference to the data structure so the only thing it can do is write/put via logToParent. If you had passed the chan/var to the child then it could accidentally start reading from it. Which would be bad. All this is an example of the "Haskell is the best imperative language" saying. An OO language might need a whole class/inferance structure to support what "writeChan chan" accomplished by currying. -- Chris
participants (3)
-
ChrisK
-
Joel Reymont
-
Sebastian Sylvan