@@ -27,9 +27,9 @@ module Xrefcheck.Verify
27
27
28
28
import Universum
29
29
30
- import Control.Concurrent.Async (Async , async , cancel , poll , wait , withAsync )
30
+ import Control.Concurrent.Async (Async , cancel , poll , wait , withAsync )
31
31
import Control.Exception (AsyncException (.. ), throwIO )
32
- import Control.Exception.Safe (handleAsync )
32
+ import Control.Exception.Safe (handleAsync , uninterruptibleMask_ )
33
33
import Control.Monad.Except (MonadError (.. ))
34
34
import Data.Bits (toIntegralSized )
35
35
import Data.ByteString qualified as BS
@@ -415,7 +415,7 @@ verifyRepo
415
415
416
416
progressRef <- newIORef $ initVerifyProgress (map snd toScan)
417
417
domainsReturned429Ref <- newIORef S. empty
418
- accumulated <- loopAsyncUntil (printer progressRef) do
418
+ accumulated <- withAsync (printer progressRef) $ \ _ ->
419
419
forConcurrentlyCaching toScan ifExternalThenCache $ \ (file, ref) ->
420
420
verifyReference config mode domainsReturned429Ref progressRef repoInfo file ref
421
421
case accumulated of
@@ -436,14 +436,15 @@ verifyRepo
436
436
printer progressRef = do
437
437
posixTime <- getPOSIXTime <&> posixTimeToTimeSecond
438
438
progress <- atomicModifyIORef' progressRef $ \ VerifyProgress {.. } ->
439
- let prog = VerifyProgress { vrExternal =
440
- checkTaskTimestamp posixTime vrExternal
441
- , ..
442
- }
439
+ let prog = VerifyProgress
440
+ { vrExternal = checkTaskTimestamp posixTime vrExternal
441
+ , ..
442
+ }
443
443
in (prog, prog)
444
- reprintAnalyseProgress rw mode posixTime progress
444
+ uninterruptibleMask_ $ reprintAnalyseProgress rw mode posixTime progress
445
445
-- Slight pause so we're not refreshing the progress bar more often than needed.
446
446
threadDelay (ms 100 )
447
+ printer progressRef
447
448
448
449
ifExternalThenCache :: (a , Reference ) -> NeedsCaching Text
449
450
ifExternalThenCache (_, Reference {.. }) =
@@ -825,28 +826,3 @@ checkExternalResource followed config@Config{..} link
825
826
pure ()
826
827
where
827
828
handler = if secure then withFTPS else withFTP
828
-
829
- ----------------------------------------------------------------------------
830
- -- Helpers
831
- ----------------------------------------------------------------------------
832
-
833
- -- | @loopAsyncUntil ma mb@ will continually run @ma@ until @mb@ throws an exception or returns.
834
- -- Once it does, it'll wait for @ma@ to finish running one last time and then return.
835
- --
836
- -- See #163 to read more on why it's important to let @ma@ finish cleanly.
837
- -- * https://github.com/serokell/xrefcheck/issues/162
838
- -- * https://github.com/serokell/xrefcheck/pull/163
839
- loopAsyncUntil :: forall a b . IO a -> IO b -> IO b
840
- loopAsyncUntil loopingAction action =
841
- mask $ \ restore -> do
842
- shouldLoop <- newIORef True
843
- loopingActionAsync <- async $ restore $ loopingAction' shouldLoop
844
- restore action `finally` do
845
- writeIORef shouldLoop False
846
- wait loopingActionAsync
847
- where
848
- loopingAction' :: IORef Bool -> IO ()
849
- loopingAction' shouldLoop = do
850
- whenM (readIORef shouldLoop) do
851
- void loopingAction
852
- loopingAction' shouldLoop
0 commit comments