Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auto-update: mkDebounce leaking the thread #980

Open
Yuras opened this issue Mar 21, 2024 · 2 comments
Open

auto-update: mkDebounce leaking the thread #980

Yuras opened this issue Mar 21, 2024 · 2 comments

Comments

@Yuras
Copy link

Yuras commented Mar 21, 2024

mkDebounce internally forks a thread, but never kills it. To reproduce, run the following with +RTS -s -RTS and observe memory usage.

import Control.Debounce
import Control.Monad

main :: IO ()
main = forM_ [(0::Int) .. 100000] $ \_ -> do
  r <- mkDebounce defaultDebounceSettings
  r

Output:

     250,129,600 bytes allocated in the heap
     417,814,184 bytes copied during GC
      47,018,288 bytes maximum residency (8 sample(s))
       3,325,648 bytes maximum slop
             132 MiB total memory in use (0 MB lost due to fragmentation)

132MiB memory is too much for the above program.

As a possible solution, consider attaching a finalizer to the debounced action that will kill the thread. I'd be happy to prepare a patch if you agree with such a solution.
Other possibility is to use a closable channel instead of MVar. I didn't try it though.

A bit of context: fast-logger uses mkDebounce to flush logs, so each logger comes with a thread which never exits.

Thanks!

@Vlix
Copy link
Contributor

Vlix commented May 21, 2024

I wonder how this could be fixed.

I guess mkDebounce could also provide a finalizer?

Or create a function that captures its own MVar and doesn't need to fork a thread?

mkDebounce :: IO () -> IO (IO ())
mkDebounce action = do
  baton <- newMVar ()
  pure $ do
    mBaton <- tryTakeMVar baton
    case mBaton of
      Nothing -> pure ()
      Just () -> do
        -- handle Leading/Trailing
        -- and `putMVar ()` when done with action + delay

@kazu-yamamoto would this idea be an ok replacement for Control.Debounce.mkDebounce? Or do you see any issues with it? (a finally putMVar might also be needed, come to think of it)

@kazu-yamamoto
Copy link
Contributor

This module was created by @snoyberg.
I don't have strong opinions but yes, cleaning up threads is a MUST.

@Vlix Vlix mentioned this issue Jun 8, 2024
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants