extend transferrer protocol to send progress bar total size updates

New protocol is not back-compat with old one, but it's never been
released so that's ok.
This commit is contained in:
Joey Hess 2020-12-11 12:39:00 -04:00
parent 94b323a8e8
commit 095cdc7e83
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
6 changed files with 44 additions and 22 deletions

View file

@ -317,7 +317,7 @@ mkPrompter = getConcurrency >>= \case
let (run, cleanup) = case outputType s of let (run, cleanup) = case outputType s of
SerializedOutput h hr -> SerializedOutput h hr ->
( \a -> do ( \a -> do
liftIO $ outputSerialized h StartPrompt liftIO $ outputSerialized h BeginPrompt
liftIO $ waitOutputSerializedResponse hr ReadyPrompt liftIO $ waitOutputSerializedResponse hr ReadyPrompt
a a
, liftIO $ outputSerialized h EndPrompt , liftIO $ outputSerialized h EndPrompt

View file

@ -25,6 +25,7 @@ import Messages.Internal
import qualified System.Console.Regions as Regions import qualified System.Console.Regions as Regions
import qualified System.Console.Concurrent as Console import qualified System.Console.Concurrent as Console
import Control.Monad.IO.Class (MonadIO) import Control.Monad.IO.Class (MonadIO)
import Data.IORef
{- Class of things from which a size can be gotten to display a progress {- Class of things from which a size can be gotten to display a progress
- meter. -} - meter. -}
@ -115,8 +116,16 @@ metered' st othermeter msize showoutput a = go st
a meter (combinemeter m) a meter (combinemeter m)
| otherwise = nometer | otherwise = nometer
go (MessageState { outputType = SerializedOutput h _ }) = do go (MessageState { outputType = SerializedOutput h _ }) = do
liftIO $ outputSerialized h $ StartProgressMeter msize liftIO $ outputSerialized h $ BeginProgressMeter msize
meter <- liftIO $ mkMeter msize $ \_ _ _old new -> szv <- liftIO $ newIORef msize
meter <- liftIO $ mkMeter msize $ \_ msize' _old new -> do
case msize' of
Just sz | msize' /= msize -> do
psz <- readIORef szv
when (msize' /= psz) $ do
writeIORef szv msize'
outputSerialized h $ UpdateProgressMeterTotalSize sz
_ -> noop
outputSerialized h $ UpdateProgressMeter $ outputSerialized h $ UpdateProgressMeter $
meterBytesProcessed new meterBytesProcessed new
m <- liftIO $ rateLimitMeterUpdate minratelimit meter $ m <- liftIO $ rateLimitMeterUpdate minratelimit meter $

View file

@ -20,7 +20,7 @@ import Messages
import Messages.Internal import Messages.Internal
import Messages.Progress import Messages.Progress
import qualified Messages.JSON as JSON import qualified Messages.JSON as JSON
import Utility.Metered (BytesProcessed) import Utility.Metered (BytesProcessed, setMeterTotalSize)
import Control.Monad.IO.Class (MonadIO) import Control.Monad.IO.Class (MonadIO)
@ -63,12 +63,12 @@ relaySerializedOutput getso sendsor meterreport runannex = go Nothing
outputSerialized h $ JSONObject b outputSerialized h $ JSONObject b
_ -> q _ -> q
loop st loop st
Left (StartProgressMeter sz) -> do Left (BeginProgressMeter sz) -> do
ost <- runannex (Annex.getState Annex.output) ost <- runannex (Annex.getState Annex.output)
-- Display a progress meter while running, until -- Display a progress meter while running, until
-- the meter ends or a final value is returned. -- the meter ends or a final value is returned.
metered' ost Nothing sz (runannex showOutput) metered' ost Nothing sz (runannex showOutput)
(\_meter meterupdate -> loop (Just meterupdate)) (\meter meterupdate -> loop (Just (meter, meterupdate)))
>>= \case >>= \case
Right r -> return (Right r) Right r -> return (Right r)
-- Continue processing serialized -- Continue processing serialized
@ -80,12 +80,18 @@ relaySerializedOutput getso sendsor meterreport runannex = go Nothing
return (Left st) return (Left st)
Left (UpdateProgressMeter n) -> do Left (UpdateProgressMeter n) -> do
case st of case st of
Just meterupdate -> do Just (_, meterupdate) -> do
meterreport (Just n) meterreport (Just n)
liftIO $ meterupdate n liftIO $ meterupdate n
Nothing -> noop Nothing -> noop
loop st loop st
Left StartPrompt -> do Left (UpdateProgressMeterTotalSize sz) -> do
case st of
Just (meter, _) -> liftIO $
setMeterTotalSize meter sz
Nothing -> noop
loop st
Left BeginPrompt -> do
prompter <- runannex mkPrompter prompter <- runannex mkPrompter
v <- prompter $ do v <- prompter $ do
sendsor ReadyPrompt sendsor ReadyPrompt

View file

@ -68,10 +68,11 @@ newMessageState = do
data SerializedOutput data SerializedOutput
= OutputMessage S.ByteString = OutputMessage S.ByteString
| OutputError String | OutputError String
| StartProgressMeter (Maybe TotalSize) | BeginProgressMeter (Maybe TotalSize)
| UpdateProgressMeter BytesProcessed | UpdateProgressMeter BytesProcessed
| UpdateProgressMeterTotalSize TotalSize
| EndProgressMeter | EndProgressMeter
| StartPrompt | BeginPrompt
| EndPrompt | EndPrompt
| JSONObject L.ByteString | JSONObject L.ByteString
-- ^ This is always sent, it's up to the consumer to decide if it -- ^ This is always sent, it's up to the consumer to decide if it

View file

@ -85,16 +85,18 @@ instance Proto.Sendable TransferResponse where
["om", Proto.serialize (encode_c (decodeBS m))] ["om", Proto.serialize (encode_c (decodeBS m))]
formatMessage (TransferOutput (OutputError e)) = formatMessage (TransferOutput (OutputError e)) =
["oe", Proto.serialize (encode_c e)] ["oe", Proto.serialize (encode_c e)]
formatMessage (TransferOutput (StartProgressMeter (Just (TotalSize n)))) = formatMessage (TransferOutput (BeginProgressMeter (Just (TotalSize n)))) =
["ops", Proto.serialize n] ["opb", Proto.serialize n]
formatMessage (TransferOutput (StartProgressMeter Nothing)) = formatMessage (TransferOutput (BeginProgressMeter Nothing)) =
["opsx"] ["opbx"]
formatMessage (TransferOutput (UpdateProgressMeter n)) = formatMessage (TransferOutput (UpdateProgressMeter n)) =
["op", Proto.serialize n] ["op", Proto.serialize n]
formatMessage (TransferOutput (UpdateProgressMeterTotalSize (TotalSize sz))) =
["ops", Proto.serialize sz]
formatMessage (TransferOutput EndProgressMeter) = formatMessage (TransferOutput EndProgressMeter) =
["ope"] ["ope"]
formatMessage (TransferOutput StartPrompt) = formatMessage (TransferOutput BeginPrompt) =
["oprs"] ["oprb"]
formatMessage (TransferOutput EndPrompt) = formatMessage (TransferOutput EndPrompt) =
["opre"] ["opre"]
formatMessage (TransferOutput (JSONObject b)) = formatMessage (TransferOutput (JSONObject b)) =
@ -109,16 +111,18 @@ instance Proto.Receivable TransferResponse where
TransferOutput . OutputMessage . encodeBS . decode_c TransferOutput . OutputMessage . encodeBS . decode_c
parseCommand "oe" = Proto.parse1 $ parseCommand "oe" = Proto.parse1 $
TransferOutput . OutputError . decode_c TransferOutput . OutputError . decode_c
parseCommand "ops" = Proto.parse1 $ parseCommand "opb" = Proto.parse1 $
TransferOutput . StartProgressMeter . Just . TotalSize TransferOutput . BeginProgressMeter . Just . TotalSize
parseCommand "opsx" = Proto.parse0 $ parseCommand "opbx" = Proto.parse0 $
TransferOutput (StartProgressMeter Nothing) TransferOutput (BeginProgressMeter Nothing)
parseCommand "op" = Proto.parse1 $ parseCommand "op" = Proto.parse1 $
TransferOutput . UpdateProgressMeter TransferOutput . UpdateProgressMeter
parseCommand "ops" = Proto.parse1 $
TransferOutput . UpdateProgressMeterTotalSize . TotalSize
parseCommand "ope" = Proto.parse0 $ parseCommand "ope" = Proto.parse0 $
TransferOutput EndProgressMeter TransferOutput EndProgressMeter
parseCommand "oprs" = Proto.parse0 $ parseCommand "oprb" = Proto.parse0 $
TransferOutput StartPrompt TransferOutput BeginPrompt
parseCommand "opre" = Proto.parse0 $ parseCommand "opre" = Proto.parse0 $
TransferOutput EndPrompt TransferOutput EndPrompt
parseCommand "oj" = Proto.parse1 $ parseCommand "oj" = Proto.parse1 $

View file

@ -3,3 +3,5 @@ communicates results in a progress display w/o ETA sometimes.
In particular, it seems to happen downloading from ssh, when the key does In particular, it seems to happen downloading from ssh, when the key does
not have a size. Normally, the size is learned during download and used in not have a size. Normally, the size is learned during download and used in
the progress bar, but somehow this does not happen. --[[Joey]] the progress bar, but somehow this does not happen. --[[Joey]]
> [[fixed|done]] --[[Joey]]