reactive-banana icon indicating copy to clipboard operation
reactive-banana copied to clipboard

`pause` does not unregister handlers

Open TobBrandt opened this issue 9 years ago • 1 comments

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?

TobBrandt avatar Nov 21 '14 20:11 TobBrandt

That's a good point, thanks! I will only fix the documentation for now, but I will address the issue in a future version.

HeinrichApfelmus avatar Dec 21 '14 19:12 HeinrichApfelmus