You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When getKeys (our updateAction) throws an exception on the second request, the request to autoUpdatingGetKeys hangs indefinitely. Any follow-up requests fail with the following error:
Control.AutoUpdate.mkAutoUpdate: worker thread exited with exception: divide by zero
CallStack (from HasCallStack):
error, called at ./Control/AutoUpdate.hs:139:48 in auto-update-0.1.6-KsptkzhzORuBNp20wquSMB:Control.AutoUpdate
Expected Behaviour
Reading the source code of auto-update the code claims that the worker thread should
only be able to exit in case of an unexpected async exception (and even says that the only case
that can happen is RTS exceptions). However in this case it also exits when updateAction throws
a synchronous exception. This feels like a bug to me.
Control.AutoUpdate.mkAutoUpdate: worker thread exited with exception: divide by zero
CallStack (from HasCallStack):
error, called at ./Control/AutoUpdate.hs:139:48 in auto-update-0.1.6-KsptkzhzORuBNp20wquSMB:Control.AutoUpdate
{-# LANGUAGE OverloadedStrings #-}
moduleMainwhereimportControl.AutoUpdate
( UpdateSettings (updateAction),
defaultUpdateSettings,
mkAutoUpdate,
)
importControl.Exception (ArithException (DivideByZero), throwIO)
importData.ByteString.Lazy (ByteString)
importNetwork.HTTP.Types (status200)
importNetwork.Wai (Application, responseLBS)
importNetwork.Wai.Handler.Warp (run)
importGHC.IORef ( IORef, newIORef, readIORef, writeIORef )
main::IO()
main =do
state <- newIORef Ok
getKeys' <- autoUpdatingGetKeys state
run 8080$ app getKeys'
dataState=Ok | NotOkderiving (Enum)
autoUpdatingGetKeys::IORefState->IO (IOByteString)
autoUpdatingGetKeys state = mkAutoUpdate (defaultUpdateSettings {updateAction = getKeys state})
getKeys::IORefState->IOByteString
getKeys state =do
s <- readIORef state
case s ofOk->do
writeIORef state NotOkreturn"hello"NotOk->do
writeIORef state Ok
throwIO DivideByZeroapp::IOByteString->Application
app getKeys' _ respond =do
response <- getKeys'
respond $ responseLBS status200 [] response
The usage of this in warp is to get the current time - which never throws an exception. So perhaps the code wasn't written
with the intent to be resilient against exceptions like I thought?
No, it wasn't. It was designed for speed, and leaves exception handling to the called function. That's an oversight in the current documentation, PR certainly welcome to clarify that.
Observed behaviour
When
getKeys
(ourupdateAction
) throws an exception on the second request, the request toautoUpdatingGetKeys
hangs indefinitely. Any follow-up requests fail with the following error:Expected Behaviour
Reading the source code of
auto-update
the code claims that the worker thread shouldonly be able to exit in case of an unexpected async exception (and even says that the only case
that can happen is RTS exceptions). However in this case it also exits when
updateAction
throwsa synchronous exception. This feels like a bug to me.
Reproducer
Now on terminal 1 you will see:
Versions used:
The text was updated successfully, but these errors were encountered: