PROPOSAL: Add newBroadcastChan :: IO (Chan a) to Control.Concurrent.Chan
 
            Ola! Control.Concurrent.STM.TChan has the “newBroadcastTChan :: STM (TChan a)”, this creates a “write-only” TChan to avoid any space leaks when a Chan is written too but never read from (for example, when dupTChan is used to hand a copy to threads). Unfortunately, no such variant seems to exist for the normal Chan? I have the following code: foo :: Chan a -> IO Foo foo broadcast = do newListener <- dupChan broadcast forkIO $ doStuffWith newListener This means the original Chan is never read from and much like the problem with TChan, values keep piling up in the original channel, causing a space leak. I propose adding newBroadcastChan :: IO (Chan a) The obvious Chan equivalent of newBroadcastTChan, which creates a write-only channel without read end, thus avoiding this space leak. Discussion: 2 weeks? Cheers, Merijn
 
            Since some people on IRC asked for an example implementation, two implementations spring to mind:
Implementation #1:
newBroadcastChan :: IO (Chan a)
newBroadcastChan = do
    hole <- newEmptyMVar
    readVar <- newMVar (error "reading from a TChan created by newBroadcastTChan; use dupTChan first")
    writeVar <- newMVar hole
    return (Chan readVar writeVar)
Pros:
 - Identical to TChan equivalent
 - Only one extra function to the API
Cons:
 - Accidental reads lead to crash
Implementation #2:
newtype BroadcastChan a = BChan (MVar (Stream a))
newBroadcastChan :: IO (BroadcastChan a)
newBroadcastChan = do
    hole <- newEmptyMVar
    writeVar <- newMVar hole
    return (BChan writeVar)
dupFromBroadcastChan :: BroadcastChan a -> IO (Chan a)
dupFromBroadcastChan (BChan writeVar) = do
    hole       <- readMVar writeVar
    newReadVar <- newMVar hole
    return (Chan newReadVar writeVar)
Pros
 - Prevents accidental reads from write-only Chan
Cons
 - Adds more new stuff to that API?
Cheers,
Merijn
On 09 Sep 2014, at 00:30 , Merijn Verstraaten 
Ola!
Control.Concurrent.STM.TChan has the “newBroadcastTChan :: STM (TChan a)”, this creates a “write-only” TChan to avoid any space leaks when a Chan is written too but never read from (for example, when dupTChan is used to hand a copy to threads). Unfortunately, no such variant seems to exist for the normal Chan? I have the following code:
foo :: Chan a -> IO Foo foo broadcast = do newListener <- dupChan broadcast forkIO $ doStuffWith newListener
This means the original Chan is never read from and much like the problem with TChan, values keep piling up in the original channel, causing a space leak. I propose adding
newBroadcastChan :: IO (Chan a)
The obvious Chan equivalent of newBroadcastTChan, which creates a write-only channel without read end, thus avoiding this space leak.
Discussion: 2 weeks?
Cheers, Merijn
participants (1)
- 
                 Merijn Verstraaten Merijn Verstraaten