2012-08-28 18:04:28 +00:00
|
|
|
{- git-annex assistant transfer polling thread
|
|
|
|
-
|
2015-01-21 16:50:09 +00:00
|
|
|
- Copyright 2012 Joey Hess <id@joeyh.name>
|
2012-08-28 18:04:28 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2012-08-28 18:04:28 +00:00
|
|
|
-}
|
|
|
|
|
|
|
|
module Assistant.Threads.TransferPoller where
|
|
|
|
|
|
|
|
import Assistant.Common
|
|
|
|
import Assistant.DaemonStatus
|
2016-08-03 16:37:12 +00:00
|
|
|
import Types.Transfer
|
2012-08-28 18:04:28 +00:00
|
|
|
import Logs.Transfer
|
|
|
|
import Utility.NotificationBroadcaster
|
2012-09-20 21:24:40 +00:00
|
|
|
import qualified Assistant.Threads.TransferWatcher as TransferWatcher
|
2012-08-28 18:04:28 +00:00
|
|
|
|
|
|
|
import Control.Concurrent
|
|
|
|
import qualified Data.Map as M
|
|
|
|
|
|
|
|
{- This thread polls the status of ongoing transfers, determining how much
|
|
|
|
- of each transfer is complete. -}
|
2012-10-29 06:21:04 +00:00
|
|
|
transferPollerThread :: NamedThread
|
2013-01-26 06:09:33 +00:00
|
|
|
transferPollerThread = namedThread "TransferPoller" $ do
|
2012-10-29 06:21:04 +00:00
|
|
|
g <- liftAnnex gitRepo
|
2013-03-27 18:56:15 +00:00
|
|
|
tn <- liftIO . newNotificationHandle True =<<
|
2012-10-30 18:44:18 +00:00
|
|
|
transferNotifier <$> getDaemonStatus
|
2012-08-28 18:04:28 +00:00
|
|
|
forever $ do
|
2012-10-29 06:21:04 +00:00
|
|
|
liftIO $ threadDelay 500000 -- 0.5 seconds
|
2012-10-30 18:44:18 +00:00
|
|
|
ts <- currentTransfers <$> getDaemonStatus
|
2012-08-28 18:04:28 +00:00
|
|
|
if M.null ts
|
2012-10-29 06:21:04 +00:00
|
|
|
-- block until transfers running
|
|
|
|
then liftIO $ waitNotification tn
|
2012-08-28 18:04:28 +00:00
|
|
|
else mapM_ (poll g) $ M.toList ts
|
2012-10-29 06:21:04 +00:00
|
|
|
where
|
|
|
|
poll g (t, info)
|
|
|
|
{- Downloads are polled by checking the size of the
|
|
|
|
- temp file being used for the transfer. -}
|
|
|
|
| transferDirection t == Download = do
|
2014-02-26 20:52:56 +00:00
|
|
|
let f = gitAnnexTmpObjectLocation (transferKey t) g
|
2020-11-05 15:26:34 +00:00
|
|
|
sz <- liftIO $ catchMaybeIO $ getFileSize f
|
2012-10-29 06:21:04 +00:00
|
|
|
newsize t info sz
|
|
|
|
{- Uploads don't need to be polled for when the TransferWatcher
|
|
|
|
- thread can track file modifications. -}
|
|
|
|
| TransferWatcher.watchesTransferSize = noop
|
|
|
|
{- Otherwise, this code polls the upload progress
|
|
|
|
- by reading the transfer info file. -}
|
|
|
|
| otherwise = do
|
fix transfer lock file for Download to not include uuid
While redundant concurrent transfers were already prevented in most
cases, it failed to prevent the case where two different repositories were
sending the same content to the same repository. By removing the uuid
from the transfer lock file for Download transfers, one repository
sending content will block the other one from also sending the same
content.
In order to interoperate with old git-annex, the old lock file is still
locked, as well as locking the new one. That added a lot of extra code
and work, and the plan is to eventually stop locking the old lock file,
at some point in time when an old git-annex process is unlikely to be
running at the same time.
Note that in the case of 2 repositories both doing eg
`git-annex copy foo --to origin`
the output is not that great:
copy b (to origin...)
transfer already in progress, or unable to take transfer lock
git-annex: transfer already in progress, or unable to take transfer lock
97% 966.81 MiB 534 GiB/s 0sp2pstdio: 1 failed
Lost connection (fd:14: hPutBuf: resource vanished (Broken pipe))
Transfer failed
Perhaps that output could be cleaned up? Anyway, it's a lot better than letting
the redundant transfer happen and then failing with an obscure error about
a temp file, which is what it did before. And it seems users don't often
try to do this, since nobody ever reported this bug to me before.
(The "97%" there is actually how far along the *other* transfer is.)
Sponsored-by: Joshua Antonishen on Patreon
2024-03-25 18:47:38 +00:00
|
|
|
let (f, _, _) = transferFileAndLockFile t g
|
2012-10-29 06:21:04 +00:00
|
|
|
mi <- liftIO $ catchDefaultIO Nothing $
|
2020-11-04 18:20:37 +00:00
|
|
|
readTransferInfoFile Nothing (fromRawFilePath f)
|
2012-10-29 06:21:04 +00:00
|
|
|
maybe noop (newsize t info . bytesComplete) mi
|
|
|
|
|
|
|
|
newsize t info sz
|
2013-04-11 20:36:45 +00:00
|
|
|
| bytesComplete info /= sz && isJust sz =
|
2012-10-30 19:39:15 +00:00
|
|
|
alterTransferInfo t $ \i -> i { bytesComplete = sz }
|
2012-10-29 06:21:04 +00:00
|
|
|
| otherwise = noop
|