reactive-banana
reactive-banana copied to clipboard
`pause` does not unregister handlers
The documentation of pause
says
Pause an event network. Immediately stop producing output and unregister all event handlers for inputs.
But the code doesn't unregister anything, it just sets a flag to ignore input.
This means, that the lifetime of a network depends on the lifetime of any AddHandler
it is registered with.
For example, the memory usage of the following program will grow linearly, because addHandler
keeps a reference to every network:
{-# LANGUAGE RankNTypes #-}
module Main where
import Reactive.Banana
import Reactive.Banana.Frameworks
import Control.Monad
import Data.IORef
numNetworks = 800000
main = do
(addHandler, fire) <- newAddHandler
progRef <- newIORef 0
printProgress 0
forM_ [1 .. numNetworks] $ \n -> do
oldProg <- readIORef progRef
let newProg = round (fromIntegral n / fromIntegral numNetworks * 100)
when (newProg > oldProg) (printProgress newProg >> writeIORef progRef newProg)
net <- makeNetwork addHandler
actuate net
pause net
getLine
makeNetwork :: AddHandler () -> IO EventNetwork
makeNetwork addHandler = do
let
desc :: forall t. Frameworks t => Moment t ()
desc = do
e <- fromAddHandler addHandler
return ()
compile desc
printProgress :: Int -> IO ()
printProgress n = putStrLn $ "[" ++ replicate n '.' ++ replicate (100-n) ' ' ++ "]"
Maybe having a dispose
function would be a good idea? Or use a weak reference for registered handlers?
That's a good point, thanks! I will only fix the documentation for now, but I will address the issue in a future version.