-
Notifications
You must be signed in to change notification settings - Fork 22
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
Fix leak in H2 manager #155
Conversation
See `ManagedThreads`. Closes kazu-yamamoto#154.
@@ -19,7 +19,7 @@ import Control.Concurrent.STM | |||
import Control.Exception | |||
import qualified Control.Exception as E | |||
import Data.Foldable | |||
import Data.Map (Map) | |||
import Data.Map.Strict (Map) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this change doesn't do anything, it's just for clarity.
modifyManagedThreads (WrapManagedThreads var) f = do | ||
threads <- readTVar var | ||
let (threads', result) = f threads | ||
writeTVar var $! threads' -- strict update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the critical line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused.
If this is critical, Data.Map.Strict
is good enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that is not correct. Without the $!
, it doesn't matter which function we use, because it is never called! It will just be a thunk build up of insert .. delete .. insert .. delete .. insert ..
. That's why it's critical to force the map to WHNF (not NF), so that we actually call the function we use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are using Strict
and StrictData
but threads'
is in a tuple.
That's why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The improve-manager
branch now use modifyTVar'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that is not the reason. Strict
does not make function application strict, it only makes bindings strict. So if we have a module in which Strict
is not enabled (standing in for writeTVar
)
module A where
ignore :: a -> String
ignore _ = "Hi"
then in
{-# LANGUAGE Strict, StrictData #-}
module B where
import A
ex1, ex2, ex3 :: IO ()
ex1 = putStrLn (ignore undefined)
ex2 = putStrLn (ignore $! undefined)
ex3 = let x = undefined in putStrLn (ignore x)
ex1
prints "Hi" whereas ex2
and ex3
both throw an exception.
I'm not completely sure but I guess that the true source of this leak is |
Uhhm. |
We can convert |
I guess that https://github.com/kazu-yamamoto/http2/tree/improve-manager fixes this thread leak. |
I will try and let you know. |
I can confirm that with 5.3.8 the memory leak is gone. I am seeing a lot of uncaught |
Please don't work around it your side. BTW, I have moved the thread manager from https://github.com/kazu-yamamoto/wai/blob/check-async-exception/time-manager/System/ThreadManager.hs |
I see that the exception is leaking in |
It's not leaking. |
Ok, let me know if you have something that you'd like me to try out. Thanks for looking into this! |
My bad. I'm now considering whether or not this breaking change is acceptable. |
@edsko I have released several packages hoping that your problems are all gone! |
Haha, all my problems gone eh? 😬 Now that would be a nice Sinterklaas gift 😁 I will try it out and let you know! :-) |
@kazu-yamamoto , my man , I do believe you are right! All the grapesy tests pass, including our stress tests (which check for memory leaks) with |
See
ManagedThreads
.Closes #154.