Skip to content

Commit

Permalink
Fix HandshakeTimeout handling
Browse files Browse the repository at this point in the history
It was throwing exceptions at the wrong time.
  • Loading branch information
roberth committed May 17, 2022
1 parent b9ed5d5 commit dc77632
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions hercules-ci-agent/src/Hercules/Agent/Socket.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import Network.URI (URI, uriAuthority, uriPath, uriPort, uriQuery, uriRegName, u
import Network.WebSockets (Connection, runClientWith)
import qualified Network.WebSockets as WS
import Protolude hiding (atomically, handle, race, race_)
import UnliftIO.Async (AsyncCancelled (AsyncCancelled), race, race_)
import qualified UnliftIO
import UnliftIO.Async (race, race_)
import UnliftIO.Exception (handle)
import UnliftIO.STM (readTVarIO)
import UnliftIO.Timeout (timeout)
Expand Down Expand Up @@ -225,31 +226,29 @@ runReliableSocket socketConfig writeQueue serviceMessageChan highestAcked = kati
pass
else noAckCleanupThread' expectedN
forever do
removeTimeout <- prepareTimeout handshakeTimeoutMicroseconds HandshakeTimeout
handle logWarningPause $
withConnection' socketConfig $
\conn -> do
katipAddNamespace "Handshake" do
handshake conn removeTimeout
readThread conn `race_` writeThread conn `race_` noAckCleanupThread
withCancelableTimeout handshakeTimeoutMicroseconds HandshakeTimeout \removeTimeout -> do
withConnection' socketConfig $
\conn -> do
katipAddNamespace "Handshake" do
handshake conn removeTimeout
readThread conn `race_` writeThread conn `race_` noAckCleanupThread

handshakeTimeoutMicroseconds :: Int
handshakeTimeoutMicroseconds = 30_000_000

data HandshakeTimeout = HandshakeTimeout
deriving (Show, Exception)

prepareTimeout :: (Exception e, MonadIO m) => Int -> e -> m (IO ())
prepareTimeout delay exc = do
withCancelableTimeout :: (Exception e, MonadUnliftIO m) => Int -> e -> (IO () -> m a) -> m a
withCancelableTimeout delay exc cont = do
requestingThread <- liftIO myThreadId
tid <- liftIO $ forkIO do
do
threadDelay delay
throwTo requestingThread exc
`catch` \(_ :: AsyncCancelled) ->
-- Removal of the timeout is normal, so do nothing
pass
pure $ throwTo tid AsyncCancelled
UnliftIO.withAsync
( liftIO do
threadDelay delay
throwTo requestingThread exc
)
(cont . cancel)

msgN :: Frame o a -> Maybe Integer
msgN Frame.Msg {n = n} = Just n
Expand Down

0 comments on commit dc77632

Please sign in to comment.