-
Notifications
You must be signed in to change notification settings - Fork 263
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
Removing unliftio #1012
Removing unliftio #1012
Conversation
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.
Overall, this change seems to me as a bit too invasive.
Changing to Control.Exception
will change behaviour with regards to async exceptions. If we'd want to keep it similar without unliftio
, we'd need to use safe-exceptions
.
I'd only fall back to Control.Exception
if we make sure the masking stays the same and async exceptions are handled the same.
Unless anyone has a good argument (in every spot where catch
, throwIO
, bracket
, etc. is used) as to why we don't have to.
@@ -29,11 +29,11 @@ module System.TimeManager ( | |||
) where | |||
|
|||
import Control.Concurrent (myThreadId) | |||
import qualified Control.Exception as E |
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 think the main change because of this would be that AsyncException
s will also be ignored if they are thrown during timeoutAction
(whereas they wouldn't before)
So (I think?) this means a thread might be failed to be killed if the async exception is thrown while the timeoutAction
is running?
So we might want to change to safe-exceptions
instead of unliftio
?
putMVar var mct | ||
mbs <- takeMVar var | ||
let tm = settingsTimeout set * 1000000 | ||
mbs <- timeout tm recvFirstBS |
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 think this makes sense, but if we want to keep the same behaviour we'd have to change it to:
mbs <- unsafeUnmask $ timeout tm recvFirstBS
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 original code before unsafeUnmask does not have unsafeUnmask
.
Is it really necessary?
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 umask
in the diff is basically unsafeUnmask
. But as you described earlier, that mkConn
should be interruptable, this is unnecessary if the bracket
(or whatever is used) is from Control.Exception
instead of from UnliftIO
.
Because the whole forkWithUnmask
was a hack to get around the unliftio
functions that mask
more than necessary.
So no, I have changed my stance and adding unsafeUnmask
is indeed not necessary.
@@ -366,7 +360,7 @@ httpOverTls TLSSettings{..} set s bs0 params = | |||
case mconn of | |||
Nothing -> throwIO IncompleteHeaders | |||
Just conn -> return conn | |||
wrappedRecvN recvN n = handleAny (const mempty) $ recvN n | |||
wrappedRecvN recvN n = handle (\(SomeException _) -> mempty) $ recvN n |
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.
Again, this will now also catch (and ignore) async exceptions.
@@ -2,10 +2,10 @@ | |||
|
|||
module Network.Wai.Handler.Warp.Conduit where | |||
|
|||
import Control.Exception (assert, throwIO) |
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 throwIO
is fine if we're only throwing syncronous exceptions.
@@ -141,7 +141,7 @@ module Network.Wai.Handler.Warp ( | |||
|
|||
import Data.Streaming.Network (HostPreference) | |||
import qualified Data.Vault.Lazy as Vault | |||
import UnliftIO.Exception (SomeException, throwIO) | |||
import Control.Exception (SomeException, throwIO) |
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 throwIO
is fine if we're only throwing syncronous exceptions.
@@ -26,7 +26,7 @@ import System.Posix.IO ( | |||
openFd, | |||
setFdOption, | |||
) | |||
import UnliftIO.Exception (bracket) | |||
import Control.Exception (bracket) |
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 UnliftIO
bracket is different in that it uses uninterruptibleMask_
on the after
actions. How important are the terminate
actions?
They are cleaning up file descriptors, so that might be important enough to absolutely make sure it happens, right?
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.
Resouce-release actions in bracket
(i.e. mask
ed actions) are iterruptible only if they are blocked (such as takeMVar
).
Non-blocking actions are NOT iterruptible.
In other words, asynchronous exceptions are not delivered to resource-release actions if they are non-blocking.
terminate
is non-blocking, so it's free from asynchronous exceptions, I believe.
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.
Ah, yes. Never mind. I've re-read the bracket
docs, and it does. I misread, I think.
@@ -7,14 +7,14 @@ module Network.Wai.Handler.Warp.FileInfoCache ( | |||
getInfo, -- test purpose only | |||
) where | |||
|
|||
import Control.Exception (bracket, onException, throwIO) |
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.
UnliftIO.onException
also runs with uninterruptibleMask
. Making sure async exceptions wait until after the cleanup is done.
@@ -7,7 +7,7 @@ module Network.Wai.Handler.Warp.Types where | |||
import qualified Data.ByteString as S | |||
import Data.IORef (IORef, newIORef, readIORef, writeIORef) | |||
import Data.Typeable (Typeable) | |||
import qualified UnliftIO | |||
import qualified Control.Exception as E |
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.
import Control.Exception as E (Exception, SomeException)
@Vlix Thank you for reviewing. |
I can understand that. |
I remembered one this. Some people believe that |
Aaaah, that's why! Ok, so what I think we should probably do:
Adding comments at those sections describing why we're using regular |
This PR removes
unliftio
from WAI families.This is because TLS
bye
and networkgracefulClose
cannot used withbracket
ofunliftio
.In my field testing for a week, I have not found any problems.
This PR is just to run CI.