use total size from DATA
Noticed that getting a key whose size is not known resulted in a progress display that didn't include the percent complete. Fixed for P2P by making the size sent with DATA be used to update the meter's total size. In order for rateLimitMeterUpdate to also learn the total size, had to make it be passed the Meter, and some other reorg in Utility.Metered was also done so that --json-progress can construct a Meter to pass to rateLimitMeterUpdate. When the fallback rsync is done, the progress display still doesn't include the percent complete. Only way to fix that seems to be to let rsync display its output again, but that would conflict with git-annex's own progress meter, which is also being displayed. This commit was sponsored by Henrik Riomar on Patreon.
This commit is contained in:
parent
b96b845ffd
commit
e16b069331
7 changed files with 68 additions and 47 deletions
|
@ -1,6 +1,6 @@
|
|||
{- Metered IO and actions
|
||||
-
|
||||
- Copyright 2012-2016 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2012-2018 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- License: BSD-2-clause
|
||||
-}
|
||||
|
@ -288,14 +288,14 @@ outputFilter cmd params environ outfilter errfilter = catchBoolIO $ do
|
|||
-- | Limit a meter to only update once per unit of time.
|
||||
--
|
||||
-- It's nice to display the final update to 100%, even if it comes soon
|
||||
-- after a previous update. To make that happen, a total size has to be
|
||||
-- provided.
|
||||
rateLimitMeterUpdate :: NominalDiffTime -> Maybe Integer -> MeterUpdate -> IO MeterUpdate
|
||||
rateLimitMeterUpdate delta totalsize meterupdate = do
|
||||
-- after a previous update. To make that happen, the Meter has to know
|
||||
-- its total size.
|
||||
rateLimitMeterUpdate :: NominalDiffTime -> Meter -> MeterUpdate -> IO MeterUpdate
|
||||
rateLimitMeterUpdate delta (Meter totalsizev _ _ _) meterupdate = do
|
||||
lastupdate <- newMVar (toEnum 0 :: POSIXTime)
|
||||
return $ mu lastupdate
|
||||
where
|
||||
mu lastupdate n@(BytesProcessed i) = case totalsize of
|
||||
mu lastupdate n@(BytesProcessed i) = tryReadMVar totalsizev >>= \case
|
||||
Just t | i >= t -> meterupdate n
|
||||
_ -> do
|
||||
now <- getPOSIXTime
|
||||
|
@ -306,35 +306,40 @@ rateLimitMeterUpdate delta totalsize meterupdate = do
|
|||
meterupdate n
|
||||
else putMVar lastupdate prev
|
||||
|
||||
data Meter = Meter (Maybe Integer) (MVar MeterState) (MVar String) RenderMeter DisplayMeter
|
||||
data Meter = Meter (MVar Integer) (MVar MeterState) (MVar String) DisplayMeter
|
||||
|
||||
type MeterState = (BytesProcessed, POSIXTime)
|
||||
|
||||
type DisplayMeter = MVar String -> String -> IO ()
|
||||
type DisplayMeter = MVar String -> Maybe Integer -> (BytesProcessed, POSIXTime) -> (BytesProcessed, POSIXTime) -> IO ()
|
||||
|
||||
type RenderMeter = Maybe Integer -> (BytesProcessed, POSIXTime) -> (BytesProcessed, POSIXTime) -> String
|
||||
|
||||
-- | Make a meter. Pass the total size, if it's known.
|
||||
mkMeter :: Maybe Integer -> RenderMeter -> DisplayMeter -> IO Meter
|
||||
mkMeter totalsize rendermeter displaymeter = Meter
|
||||
<$> pure totalsize
|
||||
mkMeter :: Maybe Integer -> DisplayMeter -> IO Meter
|
||||
mkMeter totalsize displaymeter = Meter
|
||||
<$> maybe newEmptyMVar newMVar totalsize
|
||||
<*> ((\t -> newMVar (zeroBytesProcessed, t)) =<< getPOSIXTime)
|
||||
<*> newMVar ""
|
||||
<*> pure rendermeter
|
||||
<*> pure displaymeter
|
||||
|
||||
setMeterTotalSize :: Meter -> Integer -> IO ()
|
||||
setMeterTotalSize (Meter totalsizev _ _ _) totalsize = do
|
||||
void $ tryTakeMVar totalsizev
|
||||
putMVar totalsizev totalsize
|
||||
|
||||
-- | Updates the meter, displaying it if necessary.
|
||||
updateMeter :: Meter -> BytesProcessed -> IO ()
|
||||
updateMeter (Meter totalsize sv bv rendermeter displaymeter) new = do
|
||||
updateMeter (Meter totalsizev sv bv displaymeter) new = do
|
||||
now <- getPOSIXTime
|
||||
(old, before) <- swapMVar sv (new, now)
|
||||
when (old /= new) $
|
||||
displaymeter bv $
|
||||
rendermeter totalsize (old, before) (new, now)
|
||||
when (old /= new) $ do
|
||||
totalsize <- tryReadMVar totalsizev
|
||||
displaymeter bv totalsize (old, before) (new, now)
|
||||
|
||||
-- | Display meter to a Handle.
|
||||
displayMeterHandle :: Handle -> DisplayMeter
|
||||
displayMeterHandle h v s = do
|
||||
displayMeterHandle :: Handle -> RenderMeter -> DisplayMeter
|
||||
displayMeterHandle h rendermeter v msize old new = do
|
||||
let s = rendermeter msize old new
|
||||
olds <- swapMVar v s
|
||||
-- Avoid writing when the rendered meter has not changed.
|
||||
when (olds /= s) $ do
|
||||
|
@ -344,7 +349,7 @@ displayMeterHandle h v s = do
|
|||
|
||||
-- | Clear meter displayed by displayMeterHandle.
|
||||
clearMeterHandle :: Meter -> Handle -> IO ()
|
||||
clearMeterHandle (Meter _ _ v _ _) h = do
|
||||
clearMeterHandle (Meter _ _ v _) h = do
|
||||
olds <- readMVar v
|
||||
hPutStr h $ '\r' : replicate (length olds) ' ' ++ "\r"
|
||||
hFlush h
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue