refactor(utils): minor changes for timeoutHandler

This commit is contained in:
Steffen Jost 2024-01-30 15:32:46 +01:00
parent 4154b1f26b
commit d1fce58ec2
2 changed files with 17 additions and 11 deletions

View File

@ -35,7 +35,7 @@ import Handler.Utils.Qualification as Handler.Utils
import Handler.Utils.Term as Handler.Utils import Handler.Utils.Term as Handler.Utils
import Handler.Utils.Concurrent as Handler.Utils -- import Handler.Utils.Concurrent as Handler.Utils -- only imported when needed
import Control.Monad.Logger import Control.Monad.Logger

View File

@ -3,30 +3,36 @@
-- SPDX-License-Identifier: AGPL-3.0-or-later -- SPDX-License-Identifier: AGPL-3.0-or-later
module Handler.Utils.Concurrent module Handler.Utils.Concurrent
( module Handler.Utils.Concurrent ( module Handler.Utils.Concurrent
) where ) where
-- NOTE: use `retrySTM` and `checkSTM` instead of `retry` or `check`
import Import import Import
import UnliftIO.Concurrent import UnliftIO.Concurrent as Handler.Utils.Concurrent hiding (yield)
-- | Run a handler action until it finishes or if it exceeds a given number of microseconds via `registerDelay` -- | Run a handler action until it finishes or if it exceeds a given number of microseconds via `registerDelay`
timeoutHandler :: Int -> HandlerFor site a -> HandlerFor site (Maybe a) timeoutHandler :: Int -> HandlerFor site a -> HandlerFor site (Maybe a)
timeoutHandler maxWait act = do timeoutHandler maxWait act = do
innerAct <- handlerToIO innerAct <- handlerToIO
(hresult, tid) <- liftIO $ do (hresult, tid) <- liftIO $ do
hresult <- newTVarIO Nothing hresult <- newTVarIO Nothing
tid <- forkIO $ innerAct $ do tid <- forkIO $ do
res <- act res <- innerAct act
liftIO $ atomically $ writeTVar hresult $ Just res atomically $ writeTVar hresult $ Just res
return (hresult, tid) return (hresult, tid)
res <- liftIO $ do res <- liftIO $ do
flag <- registerDelay maxWait flag <- registerDelay maxWait
atomically $ do atomically $ do
res <- readTVar hresult
out <- readTVar flag out <- readTVar flag
res <- readTVar hresult
checkSTM $ out || isJust res checkSTM $ out || isJust res
return res return res
when (isNothing res) $ killThread tid case res of
return res Nothing -> liftIO $ do
killThread tid
readTVarIO hresult -- read once more after kill to ensure that any result is noticed
_ -> return res