[Haskell-cafe] Space leak with recursion
Martijn Rijkeboer
haskell at bunix.org
Fri Apr 24 07:45:28 UTC 2015
Hi,
> I'm trying to make an observable (code below) that listens to two
> ZeroMQ sockets and publishes the received messages on a third. Every
> message that is received gets an incremented sequence number before it
> is send on the publishing socket. To keep the current sequence number a
> state object is passed to the polling function and after handling the
> message, the polling function is called again with the updated state.
>
> Unfortunately this recursive calling of the polling function creates a
> space leak. Any suggestions how to fix this?
>
> Note: for brevity I left the incrementing of the sequence number and
> the sending on the publishing socket out of the code.
As David Feuer pointed out in a private mail, I didn't include all
necessary information:
- OS: Windows 7 (64-bit)
- GHC: 7.8.4 (64-bit) (minghc)
- Zeromq4-haskell: 0.6.3 (Stackage LTS 2.4)
- ZeroMQ DLL: 4.0.4 (64-bit)
The memory usage increases with every message that is received and
is probably due to the recursive pollSockets call, since when I remove
the recursive pollSockets calls in the observerHandleEvts and
snapshotHandleEvts functions and use forever in pollSockets the memory
usage stays constant.
Kind regards,
Martijn Rijkeboer
> --- Code ---
>
> module Observable
> ( run
> ) where
>
> import Control.Monad (void)
> import Data.Int (Int64)
> import System.ZMQ4
>
>
> data State = State
> { nextSeqNum :: !Int64
> , listenSocket :: !(Socket Pull)
> , publishSocket :: !(Socket Pub)
> , snapSocket :: !(Socket Router)
> }
>
>
> run :: IO ()
> run = do
> withContext $ \ctx ->
> withSocket ctx Pull $ \observer ->
> withSocket ctx Pub $ \publisher ->
> withSocket ctx Router $ \snapshot -> do
> setLinger (restrict (0::Int)) observer
> bind observer "tcp://*:7010"
>
> setLinger (restrict (0::Int)) publisher
> bind publisher "tcp://*:7011"
>
> setLinger (restrict (0::Int)) snapshot
> setSendHighWM (restrict (0::Int)) snapshot
> bind snapshot "tcp://*:7013"
>
> let state = State
> { nextSeqNum = 0
> , listenSocket = observer
> , publishSocket = publisher
> , snapSocket = snapshot
> }
>
> pollSockets state
>
>
> pollSockets :: State -> IO ()
> pollSockets state =
> void $ poll (-1)
> [ Sock (listenSocket state) [In] (Just $ observerHandleEvts state)
> , Sock (snapSocket state) [In] (Just $ snapshotHandleEvts state)
> ]
>
>
> observerHandleEvts :: State -> [Event] -> IO ()
> observerHandleEvts state _ = do
> void $ receiveMulti $ listenSocket state
> pollSockets state
>
>
> snapshotHandleEvts :: State -> [Event] -> IO ()
> snapshotHandleEvts state _ = do
> void $ receiveMulti $ snapSocket state
> pollSockets state
More information about the Haskell-Cafe
mailing list