summaryrefslogtreecommitdiff
path: root/P2P
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-12-06 15:05:44 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-12-06 15:05:44 -0400
commit05c5822a7fababe816da579ac50d436fe19a6499 (patch)
tree9e0de3cd98442bba67cf439762d15a08765871cc /P2P
parent43db49626e57214820e29341aed0024dd681e7bd (diff)
added StoreContentTo
This is needed in addition to StoreContent, because retrieveKeyFile can be used to retrieve to different destination files, not only the tmp file for a key. This commit was sponsored by Ole-Morten Duesund on Patreon.
Diffstat (limited to 'P2P')
-rw-r--r--P2P/Annex.hs32
-rw-r--r--P2P/Protocol.hs44
2 files changed, 49 insertions, 27 deletions
diff --git a/P2P/Annex.hs b/P2P/Annex.hs
index 5e1763fc6..d0c00def3 100644
--- a/P2P/Annex.hs
+++ b/P2P/Annex.hs
@@ -16,7 +16,6 @@ module P2P.Annex
import Annex.Common
import Annex.Content
import Annex.Transfer
-import Annex.Notification
import P2P.Protocol
import P2P.IO
import Logs.Location
@@ -46,6 +45,9 @@ runLocal runmode runner a = case a of
tmp <- fromRepo $ gitAnnexTmpObjectLocation k
size <- liftIO $ catchDefaultIO 0 $ getFileSize tmp
runner (next (Len size))
+ FileSize f next -> do
+ size <- liftIO $ catchDefaultIO 0 $ getFileSize f
+ runner (next (Len size))
ContentSize k next -> do
let getsize = liftIO . catchMaybeIO . getFileSize
size <- inAnnex' isJust Nothing getsize k
@@ -69,16 +71,15 @@ runLocal runmode runner a = case a of
Left _ -> return Nothing
Right b -> runner (next b)
_ -> return Nothing
- WriteContent k af (Offset o) (Len l) b next -> do
+ StoreContent k af o l b next -> do
ok <- flip catchNonAsync (const $ return False) $
transfer download k af $
- getViaTmp AlwaysVerify k $ \tmp -> liftIO $ do
- withBinaryFile tmp WriteMode $ \h -> do
- when (o /= 0) $
- hSeek h AbsoluteSeek o
- L.hPut h b
- sz <- getFileSize tmp
- return (toInteger sz == l, UnVerified)
+ getViaTmp AlwaysVerify k $ \tmp ->
+ unVerified $ storefile tmp o l b
+ runner (next ok)
+ StoreContentTo dest o l b next -> do
+ ok <- flip catchNonAsync (const $ return False) $
+ storefile dest o l b
runner (next ok)
SetPresent k u next -> do
v <- tryNonAsync $ logChange k u InfoPresent
@@ -111,10 +112,17 @@ runLocal runmode runner a = case a of
next
Right _ -> runner next
where
- transfer mk k af a = case runmode of
+ transfer mk k af ta = case runmode of
-- Update transfer logs when serving.
Serving theiruuid ->
- mk theiruuid k af noRetry (const a) noNotification
+ mk theiruuid k af noRetry (const ta) noNotification
-- Transfer logs are updated higher in the stack when
-- a client.
- Client -> a
+ Client -> ta
+ storefile dest (Offset o) (Len l) b = liftIO $ do
+ withBinaryFile dest WriteMode $ \h -> do
+ when (o /= 0) $
+ hSeek h AbsoluteSeek o
+ L.hPut h b
+ sz <- getFileSize dest
+ return (toInteger sz == l)
diff --git a/P2P/Protocol.hs b/P2P/Protocol.hs
index 53c3265ef..b2b734e48 100644
--- a/P2P/Protocol.hs
+++ b/P2P/Protocol.hs
@@ -189,16 +189,25 @@ data LocalF c
= TmpContentSize Key (Len -> c)
-- ^ Gets size of the temp file where received content may have
-- been stored. If not present, returns 0.
+ | FileSize FilePath (Len -> c)
+ -- ^ Gets size of the content of a file. If not present, returns 0.
| ContentSize Key (Maybe Len -> c)
-- ^ Gets size of the content of a key, when the full content is
-- present.
| ReadContent Key AssociatedFile Offset (L.ByteString -> c)
-- ^ Lazily reads the content of a key. Note that the content
-- may change while it's being sent.
- | WriteContent Key AssociatedFile Offset Len L.ByteString (Bool -> c)
- -- ^ Writes content to temp file starting at an offset.
+ | StoreContent Key AssociatedFile Offset Len L.ByteString (Bool -> c)
+ -- ^ Stores content to the key's temp file starting at an offset.
-- Once the whole content of the key has been stored, moves the
- -- temp file into place and returns True.
+ -- temp file into place as the content of the key, and returns True.
+ --
+ -- Note: The ByteString may not contain the entire remaining content
+ -- of the key. Only once the temp file size == Len has the whole
+ -- content been transferred.
+ | StoreContentTo FilePath Offset Len L.ByteString (Bool -> c)
+ -- ^ Stores the content to a temp file starting at an offset.
+ -- Once the whole content of the key has been stored, returns True.
--
-- Note: The ByteString may not contain the entire remaining content
-- of the key. Only once the temp file size == Len has the whole
@@ -246,16 +255,16 @@ checkPresent key = do
-}
lockContentWhile
:: MonadMask m
- => (forall r. Proto r -> m r)
+ => (forall r. r -> Proto r -> m r)
-> Key
- -> (Bool -> m ())
- -> m ()
+ -> (Bool -> m a)
+ -> m a
lockContentWhile runproto key a = bracket setup cleanup a
where
- setup = runproto $ do
+ setup = runproto False $ do
net $ sendMessage (LOCKCONTENT key)
checkSuccess
- cleanup True = runproto $ net $ sendMessage UNLOCKCONTENT
+ cleanup True = runproto () $ net $ sendMessage UNLOCKCONTENT
cleanup False = return ()
remove :: Key -> Proto Bool
@@ -263,8 +272,11 @@ remove key = do
net $ sendMessage (REMOVE key)
checkSuccess
-get :: Key -> AssociatedFile -> Proto Bool
-get key af = receiveContent key af (\offset -> GET offset af key)
+get :: FilePath -> Key -> AssociatedFile -> Proto Bool
+get dest key af = receiveContent sizer storer (\offset -> GET offset af key)
+ where
+ sizer = fileSize dest
+ storer = storeContentTo dest
put :: Key -> AssociatedFile -> Proto Bool
put key af = do
@@ -349,7 +361,9 @@ serveAuthed myuuid = void $ serverLoop handler
if have
then net $ sendMessage ALREADY_HAVE
else do
- ok <- receiveContent key af PUT_FROM
+ let sizer = tmpContentSize key
+ let storer = storeContent key af
+ ok <- receiveContent sizer storer PUT_FROM
when ok $
local $ setPresent key myuuid
return ServerContinue
@@ -370,15 +384,15 @@ sendContent key af offset = do
net $ sendBytes len content
checkSuccess
-receiveContent :: Key -> AssociatedFile -> (Offset -> Message) -> Proto Bool
-receiveContent key af mkmsg = do
- Len n <- local $ tmpContentSize key
+receiveContent :: Local Len -> (Offset -> Len -> L.ByteString -> Local Bool) -> (Offset -> Message) -> Proto Bool
+receiveContent sizer storer mkmsg = do
+ Len n <- local sizer
let offset = Offset n
net $ sendMessage (mkmsg offset)
r <- net receiveMessage
case r of
DATA len -> do
- ok <- local . writeContent key af offset len
+ ok <- local . storer offset len
=<< net (receiveBytes len)
sendSuccess ok
return ok