reorg to allow taking content lock
The lock will only persist during the perform stage, so the content must be removed from the annex then, rather than in the cleanup stage. (No lock is actually taken yet.)
This commit is contained in:
parent
58563c5b1a
commit
8ce7e73f74
5 changed files with 54 additions and 26 deletions
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
module Annex.Content (
|
module Annex.Content (
|
||||||
inAnnex,
|
inAnnex,
|
||||||
|
lockExclusive,
|
||||||
|
lockShared,
|
||||||
calcGitLink,
|
calcGitLink,
|
||||||
logStatus,
|
logStatus,
|
||||||
getViaTmp,
|
getViaTmp,
|
||||||
|
@ -41,6 +43,16 @@ inAnnex key = do
|
||||||
error "inAnnex cannot check remote repo"
|
error "inAnnex cannot check remote repo"
|
||||||
inRepo $ doesFileExist . gitAnnexLocation key
|
inRepo $ doesFileExist . gitAnnexLocation key
|
||||||
|
|
||||||
|
{- Content is exclusively locked to indicate that it's in the process of
|
||||||
|
- being removed. -}
|
||||||
|
lockExclusive :: Key -> Annex a -> Annex a
|
||||||
|
lockExclusive key a = a -- TODO
|
||||||
|
|
||||||
|
{- Things that rely on content being present can take a shared lock to
|
||||||
|
- avoid it vanishing from under them. -}
|
||||||
|
lockShared :: Key -> Annex a -> Annex a
|
||||||
|
lockShared key a = a -- TODO
|
||||||
|
|
||||||
{- Calculates the relative path to use to link a file to a key. -}
|
{- Calculates the relative path to use to link a file to a key. -}
|
||||||
calcGitLink :: FilePath -> Key -> Annex FilePath
|
calcGitLink :: FilePath -> Key -> Annex FilePath
|
||||||
calcGitLink file key = do
|
calcGitLink file key = do
|
||||||
|
|
|
@ -52,17 +52,19 @@ startRemote file numcopies key remote = do
|
||||||
next $ performRemote key numcopies remote
|
next $ performRemote key numcopies remote
|
||||||
|
|
||||||
performLocal :: Key -> Maybe Int -> CommandPerform
|
performLocal :: Key -> Maybe Int -> CommandPerform
|
||||||
performLocal key numcopies = do
|
performLocal key numcopies = lockExclusive key $ do
|
||||||
(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key
|
(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key
|
||||||
untrusteduuids <- trustGet UnTrusted
|
untrusteduuids <- trustGet UnTrusted
|
||||||
let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids++untrusteduuids)
|
let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids++untrusteduuids)
|
||||||
success <- canDropKey key numcopies trusteduuids tocheck []
|
success <- canDropKey key numcopies trusteduuids tocheck []
|
||||||
if success
|
if success
|
||||||
then next $ cleanupLocal key
|
then do
|
||||||
|
whenM (inAnnex key) $ removeAnnex key
|
||||||
|
next $ cleanupLocal key
|
||||||
else stop
|
else stop
|
||||||
|
|
||||||
performRemote :: Key -> Maybe Int -> Remote.Remote Annex -> CommandPerform
|
performRemote :: Key -> Maybe Int -> Remote.Remote Annex -> CommandPerform
|
||||||
performRemote key numcopies remote = do
|
performRemote key numcopies remote = lockExclusive key $ do
|
||||||
-- Filter the remote it's being dropped from out of the lists of
|
-- Filter the remote it's being dropped from out of the lists of
|
||||||
-- places assumed to have the key, and places to check.
|
-- places assumed to have the key, and places to check.
|
||||||
-- When the local repo has the key, that's one additional copy.
|
-- When the local repo has the key, that's one additional copy.
|
||||||
|
@ -76,20 +78,20 @@ performRemote key numcopies remote = do
|
||||||
Remote.remotesWithoutUUID remotes (have++untrusteduuids)
|
Remote.remotesWithoutUUID remotes (have++untrusteduuids)
|
||||||
success <- canDropKey key numcopies have tocheck [uuid]
|
success <- canDropKey key numcopies have tocheck [uuid]
|
||||||
if success
|
if success
|
||||||
then next $ cleanupRemote key remote
|
then do
|
||||||
|
ok <- Remote.removeKey remote key
|
||||||
|
next $ cleanupRemote key remote ok
|
||||||
else stop
|
else stop
|
||||||
where
|
where
|
||||||
uuid = Remote.uuid remote
|
uuid = Remote.uuid remote
|
||||||
|
|
||||||
cleanupLocal :: Key -> CommandCleanup
|
cleanupLocal :: Key -> CommandCleanup
|
||||||
cleanupLocal key = do
|
cleanupLocal key = do
|
||||||
whenM (inAnnex key) $ removeAnnex key
|
|
||||||
logStatus key InfoMissing
|
logStatus key InfoMissing
|
||||||
return True
|
return True
|
||||||
|
|
||||||
cleanupRemote :: Key -> Remote.Remote Annex -> CommandCleanup
|
cleanupRemote :: Key -> Remote.Remote Annex -> Bool -> CommandCleanup
|
||||||
cleanupRemote key remote = do
|
cleanupRemote key remote ok = do
|
||||||
ok <- Remote.removeKey remote key
|
|
||||||
-- better safe than sorry: assume the remote dropped the key
|
-- better safe than sorry: assume the remote dropped the key
|
||||||
-- even if it seemed to fail; the failure could have occurred
|
-- even if it seemed to fail; the failure could have occurred
|
||||||
-- after it really dropped it
|
-- after it really dropped it
|
||||||
|
|
|
@ -55,7 +55,8 @@ perform key = maybe droplocal dropremote =<< Annex.getState Annex.fromremote
|
||||||
dropremote name = do
|
dropremote name = do
|
||||||
r <- Remote.byName name
|
r <- Remote.byName name
|
||||||
showAction $ "from " ++ Remote.name r
|
showAction $ "from " ++ Remote.name r
|
||||||
next $ Command.Drop.cleanupRemote key r
|
ok <- Remote.removeKey r key
|
||||||
|
next $ Command.Drop.cleanupRemote key r ok
|
||||||
droplocal = Command.Drop.performLocal key (Just 0) -- force drop
|
droplocal = Command.Drop.performLocal key (Just 0) -- force drop
|
||||||
|
|
||||||
performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
|
performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
|
||||||
|
|
|
@ -68,7 +68,7 @@ toStart dest move file = isAnnexed file $ \(key, _) -> do
|
||||||
showMoveAction move file
|
showMoveAction move file
|
||||||
next $ toPerform dest move key
|
next $ toPerform dest move key
|
||||||
toPerform :: Remote.Remote Annex -> Bool -> Key -> CommandPerform
|
toPerform :: Remote.Remote Annex -> Bool -> Key -> CommandPerform
|
||||||
toPerform dest move key = do
|
toPerform dest move key = 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,18 +88,20 @@ toPerform dest move key = do
|
||||||
showAction $ "to " ++ Remote.name dest
|
showAction $ "to " ++ Remote.name dest
|
||||||
ok <- Remote.storeKey dest key
|
ok <- Remote.storeKey dest key
|
||||||
if ok
|
if ok
|
||||||
then next $ toCleanup dest move key
|
then finish
|
||||||
else do
|
else do
|
||||||
when fastcheck $
|
when fastcheck $
|
||||||
warning "This could have failed because --fast is enabled."
|
warning "This could have failed because --fast is enabled."
|
||||||
stop
|
stop
|
||||||
Right True -> next $ toCleanup dest move key
|
Right True -> finish
|
||||||
toCleanup :: Remote.Remote Annex -> Bool -> Key -> CommandCleanup
|
where
|
||||||
toCleanup dest move key = do
|
finish = do
|
||||||
Remote.remoteHasKey dest key True
|
Remote.remoteHasKey dest key True
|
||||||
if move
|
if move
|
||||||
then Command.Drop.cleanupLocal key
|
then do
|
||||||
else return True
|
whenM (inAnnex key) $ removeAnnex key
|
||||||
|
next $ Command.Drop.cleanupLocal key
|
||||||
|
else next $ return True
|
||||||
|
|
||||||
{- Moves (or copies) the content of an annexed file from a remote
|
{- Moves (or copies) the content of an annexed file from a remote
|
||||||
- to the current repository.
|
- to the current repository.
|
||||||
|
@ -117,16 +119,23 @@ fromStart src move file = isAnnexed file $ \(key, _) -> do
|
||||||
showMoveAction move file
|
showMoveAction move file
|
||||||
next $ fromPerform src move key
|
next $ fromPerform src move key
|
||||||
fromPerform :: Remote.Remote Annex -> Bool -> Key -> CommandPerform
|
fromPerform :: Remote.Remote Annex -> Bool -> Key -> CommandPerform
|
||||||
fromPerform src move key = do
|
fromPerform src move key = moveLock move key $ do
|
||||||
ishere <- inAnnex key
|
ishere <- inAnnex key
|
||||||
if ishere
|
if ishere
|
||||||
then next $ fromCleanup src move key
|
then handle move True
|
||||||
else do
|
else 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
|
||||||
if ok
|
handle move ok
|
||||||
then next $ fromCleanup src move key
|
where
|
||||||
else stop -- fail
|
handle _ False = stop -- failed
|
||||||
fromCleanup :: Remote.Remote Annex -> Bool -> Key -> CommandCleanup
|
handle False True = next $ return True -- copy complete
|
||||||
fromCleanup src True key = Command.Drop.cleanupRemote key src
|
handle True True = do -- finish moving
|
||||||
fromCleanup _ False _ = return True
|
ok <- Remote.removeKey src key
|
||||||
|
next $ Command.Drop.cleanupRemote key src ok
|
||||||
|
|
||||||
|
{- Locks a key in order for it to be moved.
|
||||||
|
- No lock is needed when a key is being copied. -}
|
||||||
|
moveLock :: Bool -> Key -> Annex a -> Annex a
|
||||||
|
moveLock True key a = lockExclusive key a
|
||||||
|
moveLock False _ a = a
|
||||||
|
|
|
@ -38,6 +38,10 @@ distinguishable from "not in annex".
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
drop --from could also cycle. Locking should fix.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
move --to can also be included in the cycle, since it can drop data.
|
move --to can also be included in the cycle, since it can drop data.
|
||||||
|
|
||||||
Consider move to a remote that already has the content and
|
Consider move to a remote that already has the content and
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue