git-annex/Assistant/Threads/Transferrer.hs

118 lines
3.6 KiB
Haskell
Raw Normal View History

2012-07-05 20:34:20 +00:00
{- git-annex assistant data transferrer thread
-
- Copyright 2012 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Assistant.Threads.Transferrer where
import Assistant.Common
2012-07-05 20:34:20 +00:00
import Assistant.DaemonStatus
import Assistant.TransferQueue
import Assistant.TransferSlots
2012-08-06 21:09:23 +00:00
import Assistant.Alert
import Assistant.Commits
2012-11-24 20:30:15 +00:00
import Assistant.Drop
2012-07-05 20:34:20 +00:00
import Logs.Transfer
import Logs.Location
2012-07-05 20:34:20 +00:00
import Annex.Content
import qualified Remote
import Types.Key
import Locations.UserConfig
import Assistant.Threads.TransferWatcher
2012-07-05 20:34:20 +00:00
import System.Process (create_group)
2012-07-05 20:34:20 +00:00
{- Dispatches transfers from the queue. -}
transfererThread :: NamedThread
transfererThread = namedThread "Transferrer" $ do
program <- liftIO readProgramFile
forever $ inTransferSlot $
maybe (return Nothing) (uncurry $ startTransfer program)
=<< getNextTransfer notrunning
where
{- Skip transfers that are already running. -}
notrunning = isNothing . startedTime
2012-07-05 20:34:20 +00:00
2012-08-29 21:32:41 +00:00
{- By the time this is called, the daemonstatus's transfer map should
- already have been updated to include the transfer. -}
startTransfer :: FilePath -> Transfer -> TransferInfo -> Assistant (Maybe (Transfer, TransferInfo, Assistant ()))
startTransfer program t info = case (transferRemote info, associatedFile info) of
(Just remote, Just file) -> ifM (liftAnnex $ shouldTransfer t info)
( do
debug [ "Transferring:" , describeTransfer t info ]
notifyTransfer
return $ Just (t, info, transferprocess remote file)
, do
debug [ "Skipping unnecessary transfer:" , describeTransfer t info ]
void $ removeTransfer t
finishedTransfer t (Just info)
return Nothing
)
_ -> return Nothing
where
direction = transferDirection t
isdownload = direction == Download
transferprocess remote file = void $ do
(_, _, _, pid)
<- liftIO $ createProcess (proc program $ toCommand params)
{ create_group = True }
{- Alerts are only shown for successful transfers.
- Transfers can temporarily fail for many reasons,
- so there's no point in bothering the user about
- those. The assistant should recover.
-
2012-11-24 20:30:15 +00:00
- After a successful upload, handle dropping it from
- here, if desired. In this case, the remote it was
- uploaded to is known to have it.
-
- Also, after a successful transfer, the location
- log has changed. Indicate that a commit has been
- made, in order to queue a push of the git-annex
- branch out to remotes that did not participate
- in the transfer.
-}
whenM (liftIO $ (==) ExitSuccess <$> waitForProcess pid) $ do
void $ addAlert $ makeAlertFiller True $
transferFileAlert direction True file
2012-11-24 20:30:15 +00:00
unless isdownload $
handleDrops
("object uploaded to " ++ show remote)
True (transferKey t)
2012-11-24 20:30:15 +00:00
(associatedFile info)
(Just remote)
2012-10-29 23:35:18 +00:00
recordCommit
where
params =
[ Param "transferkey"
, Param "--quiet"
, Param $ key2file $ transferKey t
, Param $ if isdownload
then "--from"
else "--to"
, Param $ Remote.name remote
, Param "--file"
, File file
]
{- Checks if the file to download is already present, or the remote
- being uploaded to isn't known to have the file. -}
shouldTransfer :: Transfer -> TransferInfo -> Annex Bool
shouldTransfer t info
| transferDirection t == Download =
not <$> inAnnex key
| transferDirection t == Upload =
{- Trust the location log to check if the
- remote already has the key. This avoids
- a roundtrip to the remote. -}
case transferRemote info of
Nothing -> return False
Just remote ->
notElem (Remote.uuid remote)
<$> loggedLocations key
| otherwise = return False
2012-10-31 06:34:03 +00:00
where
key = transferKey t