[Git][ghc/ghc][wip/T24040-ghci-timeout] it works... but ghci timeouts even when you're typing right now...
Hassan Al-Awwadi (@hassan.awwadi)
gitlab at gitlab.haskell.org
Wed Dec 20 23:17:51 UTC 2023
Hassan Al-Awwadi pushed to branch wip/T24040-ghci-timeout at Glasgow Haskell Compiler / GHC
Commits:
b21bf207 by Hassan Al-Awwadi at 2023-12-21T00:17:25+01:00
it works... but ghci timeouts even when you're typing right now...
- - - - -
1 changed file:
- ghc/GHCi/UI.hs
Changes:
=====================================
ghc/GHCi/UI.hs
=====================================
@@ -111,13 +111,13 @@ import GHC.Types.Error
import System.Console.Haskeline as Haskeline
import Control.Applicative hiding (empty)
-import Control.DeepSeq (NFData, deepseq, force)
+import Control.Concurrent(myThreadId, killThread, forkIO, threadDelay)
+import Control.DeepSeq (deepseq)
import Control.Monad as Monad
import Control.Monad.Catch as MC
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Except
-import Control.Exception as E (evaluate)
import Data.Array
import qualified Data.ByteString.Char8 as BS
import Data.Char
@@ -153,7 +153,6 @@ import System.IO
import System.IO.Error
import System.IO.Unsafe ( unsafePerformIO )
import System.Process
-import System.Timeout (timeout)
import Text.Printf
import Text.Read ( readMaybe )
import Text.Read.Lex (isSymbolChar)
@@ -1084,7 +1083,7 @@ runCommands' eh sourceErrorHandler gCmd = mask $ \unmask -> do
return Nothing
_other ->
liftIO (Exception.throwIO e))
- (unmask $ withTimeLimit (Just False) $ runOneCommand eh gCmd)
+ (withTimeLimit (Just False) $ unmask $ runOneCommand eh gCmd)
case b of
Nothing -> return ()
Just success -> do
@@ -1093,16 +1092,35 @@ runCommands' eh sourceErrorHandler gCmd = mask $ \unmask -> do
-- | Wraps a single run input action into a timout action, if the timelimit field has been set.
-- | Otherwise it just runs the action without doing anything.
-withTimeLimit :: (MonadIO m, GhciMonad m, NFData a) => a -> m (a) -> m (a)
+withTimeLimit :: (MonadIO m, MonadCatch m, GhciMonad m) => a -> m a -> m a
withTimeLimit time_out_value cmd = do
maybe_limit <- time_limit <$> getGHCiState
case maybe_limit of
Nothing -> cmd
- Just limit -> do
- result_or_timeout <- liftIO . timeout limit . E.evaluate . force =<< cmd
+ Just limit -> do
+ result_or_timeout <- timeout limit cmd -- puts the IO action inside GhciMonad
case result_or_timeout of
Just fin -> pure fin
- Nothing -> printForUser (text "GhciTimedOut.") $> time_out_value
+ Nothing -> printForUser (text "GhciTimedOut.") $> time_out_value
+
+-- | I'd use System.Timeout(Timeout)
+-- | If it exported the constructor...
+data TimeoutTM = TimeoutTM deriving Show
+instance Exception TimeoutTM
+
+catchTimeout :: (MonadIO m, MonadCatch m) => m a -> m (Maybe a)
+catchTimeout action = catch (Just <$> action) $ \ TimeoutTM -> return Nothing
+
+-- | duping System.Timeout(timeout), because I needed a lifted version
+-- | a transient duping, because really this is a dupe of Control.Timeout(timeout), but that one isn't in base...
+-- | If we want this feature we'll want something like this, presumably not located here.
+timeout :: (MonadIO m, MonadCatch m) => Int -> m a -> m (Maybe a)
+timeout time action = do
+ tidMain <- liftIO myThreadId
+ tidTemp <- liftIO $ forkIO $ threadDelay (time*1000000) >> throwTo tidMain TimeoutTM -- need a better way to threaddelay in seconds rather than just multiplying with 1000 000, which feels... fragile
+ result <- catchTimeout action `MC.onException` liftIO (killThread tidTemp)
+ when (isJust result) $ liftIO $ killThread tidTemp
+ return result
-- | Evaluate a single line of user input (either :<command> or Haskell code).
-- A result of Nothing means there was no more input to process.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b21bf2073cf185bc8227c7308ece21eb8b7b14fa
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b21bf2073cf185bc8227c7308ece21eb8b7b14fa
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20231220/28398d78/attachment-0001.html>
More information about the ghc-commits
mailing list