get, move, copy: Now refuse to do anything when the requested file transfer is already in progress by another process.

Note this is per-remote, so trying to get the same file from multiple
remotes can still let duplicate downloads run. (And uploading the same file
to multiple remotes is not duplicate at all of course.)

get, move, and copy are the only git-annex subcommands that transfer
files, but there's still git-annex-shell recvkey and sendkey to deal with too.

I considered modifying retrieveKeyFile or getViaTmp, but they are called
by other code that does not involve expensive file transfers (migrate)
or that does file transfers that should not be checked by this (fsck --from).
This commit is contained in:
Joey Hess 2012-07-01 15:18:36 -04:00
parent 72988bae34
commit e5fd8b67b7
3 changed files with 26 additions and 17 deletions

View file

@ -12,6 +12,7 @@ import Command
import qualified Remote import qualified Remote
import Annex.Content import Annex.Content
import qualified Command.Move import qualified Command.Move
import Logs.Transfer
def :: [Command] def :: [Command]
def = [withOptions [Command.Move.fromOption] $ command "get" paramPaths seek def = [withOptions [Command.Move.fromOption] $ command "get" paramPaths seek
@ -25,24 +26,24 @@ start :: Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart
start from file (key, _) = stopUnless (not <$> inAnnex key) $ start from file (key, _) = stopUnless (not <$> inAnnex key) $
autoCopies file key (<) $ \_numcopies -> autoCopies file key (<) $ \_numcopies ->
case from of case from of
Nothing -> go $ perform key Nothing -> go $ perform key file
Just src -> Just src ->
-- get --from = copy --from -- get --from = copy --from
stopUnless (Command.Move.fromOk src key) $ stopUnless (Command.Move.fromOk src key) $
go $ Command.Move.fromPerform src False key go $ Command.Move.fromPerform src False key file
where where
go a = do go a = do
showStart "get" file showStart "get" file
next a next a
perform :: Key -> CommandPerform perform :: Key -> FilePath -> CommandPerform
perform key = stopUnless (getViaTmp key $ getKeyFile key) $ perform key file = stopUnless (getViaTmp key $ getKeyFile key file) $
next $ return True -- no cleanup needed next $ return True -- no cleanup needed
{- Try to find a copy of the file in one of the remotes, {- Try to find a copy of the file in one of the remotes,
- and copy it to here. -} - and copy it to here. -}
getKeyFile :: Key -> FilePath -> Annex Bool getKeyFile :: Key -> FilePath -> FilePath -> Annex Bool
getKeyFile key file = dispatch =<< Remote.keyPossibilities key getKeyFile key file dest = dispatch =<< Remote.keyPossibilities key
where where
dispatch [] = do dispatch [] = do
showNote "not available" showNote "not available"
@ -64,7 +65,7 @@ getKeyFile key file = dispatch =<< Remote.keyPossibilities key
| Remote.hasKeyCheap r = | Remote.hasKeyCheap r =
either (const False) id <$> Remote.hasKey r key either (const False) id <$> Remote.hasKey r key
| otherwise = return True | otherwise = return True
docopy r continue = do docopy r continue = download r key file $ do
showAction $ "from " ++ Remote.name r showAction $ "from " ++ Remote.name r
ifM (Remote.retrieveKeyFile r key file) ifM (Remote.retrieveKeyFile r key dest)
( return True , continue) ( return True , continue)

View file

@ -16,6 +16,7 @@ import qualified Remote
import Annex.UUID import Annex.UUID
import qualified Option import qualified Option
import Logs.Presence import Logs.Presence
import Logs.Transfer
def :: [Command] def :: [Command]
def = [withOptions options $ command "move" paramPaths seek def = [withOptions options $ command "move" paramPaths seek
@ -68,9 +69,9 @@ toStart dest move file key = do
then stop -- not here, so nothing to do then stop -- not here, so nothing to do
else do else do
showMoveAction move file showMoveAction move file
next $ toPerform dest move key next $ toPerform dest move key file
toPerform :: Remote -> Bool -> Key -> CommandPerform toPerform :: Remote -> Bool -> Key -> FilePath -> CommandPerform
toPerform dest move key = moveLock move key $ do toPerform dest move key file = moveLock move key $ do
-- Checking the remote is expensive, so not done in the start step. -- Checking the remote is expensive, so not done in the start step.
-- In fast mode, location tracking is assumed to be correct, -- In fast mode, location tracking is assumed to be correct,
-- and an explicit check is not done, when copying. When moving, -- and an explicit check is not done, when copying. When moving,
@ -88,7 +89,7 @@ toPerform dest move key = moveLock move key $ do
stop stop
Right False -> do Right False -> do
showAction $ "to " ++ Remote.name dest showAction $ "to " ++ Remote.name dest
ok <- Remote.storeKey dest key ok <- upload dest key file $ Remote.storeKey dest key
if ok if ok
then finish then finish
else do else do
@ -118,7 +119,7 @@ fromStart src move file key
where where
go = stopUnless (fromOk src key) $ do go = stopUnless (fromOk src key) $ do
showMoveAction move file showMoveAction move file
next $ fromPerform src move key next $ fromPerform src move key file
fromOk :: Remote -> Key -> Annex Bool fromOk :: Remote -> Key -> Annex Bool
fromOk src key fromOk src key
| Remote.hasKeyCheap src = | Remote.hasKeyCheap src =
@ -129,11 +130,11 @@ fromOk src key
u <- getUUID u <- getUUID
remotes <- Remote.keyPossibilities key remotes <- Remote.keyPossibilities key
return $ u /= Remote.uuid src && elem src remotes return $ u /= Remote.uuid src && elem src remotes
fromPerform :: Remote -> Bool -> Key -> CommandPerform fromPerform :: Remote -> Bool -> Key -> FilePath -> CommandPerform
fromPerform src move key = moveLock move key $ fromPerform src move key file = moveLock move key $
ifM (inAnnex key) ifM (inAnnex key)
( handle move True ( handle move True
, do , download src key file $ do
showAction $ "from " ++ Remote.name src showAction $ "from " ++ Remote.name src
ok <- getViaTmp key $ Remote.retrieveKeyFile src key ok <- getViaTmp key $ Remote.retrieveKeyFile src key
handle move ok handle move ok

7
debian/changelog vendored
View file

@ -1,3 +1,10 @@
git-annex (3.20120630) UNRELEASED; urgency=low
* get, move, copy: Now refuse to do anything when the requested file
transfer is already in progress by another process.
-- Joey Hess <joeyh@debian.org> Sun, 01 Jul 2012 15:04:37 -0400
git-annex (3.20120629) unstable; urgency=low git-annex (3.20120629) unstable; urgency=low
* cabal: Only try to use inotify on Linux. * cabal: Only try to use inotify on Linux.