support DATA-PRESENT in the p2p protocol proxy

But not yet when proxying to special remotes.

When proxying for a cluster, the client can store the object on any node
or nodes of the cluster, and send DATA-PRESENT. That gets proxied to each
node, and if any of them agree that they have the data, the proxy will
respond with SUCCESS or SUCCESS-PLUS.

I think it's ok to not check for the proxied remotes supporting protocol
version 4. When there are multiple remotes in a cluster, it behaves as
described above, and if they all respond with ERROR, the result will be
FAILURE. And when not proxying for a cluster, the proxy negotiates the
p2p protocol to be the same version or lower than the proxied remote,
which will prevent sending DATA-PRESENT when it's too old.
This commit is contained in:
Joey Hess 2024-10-29 14:20:07 -04:00
parent a4e9057486
commit 2fc3fbfed2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38

View file

@ -302,6 +302,7 @@ proxyRequest proxydone proxyparams requestcomplete requestmessage protoerrhandle
FAILURE -> protoerr
FAILURE_PLUS _ -> protoerr
DATA _ -> protoerr
DATA_PRESENT -> protoerr
VALIDITY _ -> protoerr
UNLOCKCONTENT -> protoerr
-- If the client errors out, give up.
@ -486,7 +487,7 @@ proxyRequest proxydone proxyparams requestcomplete requestmessage protoerrhandle
getresponse client resp $
withDATA
(relayPUT remoteside k)
(const protoerr)
(handlePut_DATA_PRESENT remoteside k)
_ -> protoerr
handlePUT [] _ _ =
protoerrhandler requestcomplete $
@ -563,7 +564,7 @@ proxyRequest proxydone proxyparams requestcomplete requestmessage protoerrhandle
let minoffset = minimum (map snd l')
getresponse client (PUT_FROM (Offset minoffset)) $
withDATA (relayPUTMulti minoffset l' k)
(const protoerr)
(handlePutMulti_DATA_PRESENT l' k)
relayPUTMulti minoffset remotes k (Len datalen) _ = do
-- Tell each remote how much data to expect, depending
@ -664,6 +665,9 @@ proxyRequest proxydone proxyparams requestcomplete requestmessage protoerrhandle
Just (Just resp) ->
relayPUTRecord k r resp
_ -> return Nothing
relayDATAFinishMulti' storeduuids
relayDATAFinishMulti' storeduuids =
protoerrhandler requestcomplete $
client $ net $ sendMessage $
case concat (catMaybes storeduuids) of
@ -672,6 +676,23 @@ proxyRequest proxydone proxyparams requestcomplete requestmessage protoerrhandle
| proxyClientProtocolVersion proxyparams < ProtocolVersion 2 -> SUCCESS
| otherwise -> SUCCESS_PLUS us
handlePutMulti_DATA_PRESENT remotes k DATA_PRESENT = do
storeduuids <- forMC (proxyConcurrencyConfig proxyparams) remotes $ \(remoteside, _) -> do
resp <- runRemoteSideOrSkipFailed remoteside $ do
net $ sendMessage DATA_PRESENT
net receiveMessage
case resp of
Just (Just resp') -> relayPUTRecord k remoteside resp'
_ -> return Nothing
relayDATAFinishMulti' storeduuids
handlePutMulti_DATA_PRESENT _ _ _ = protoerr
handlePut_DATA_PRESENT remoteside k DATA_PRESENT =
getresponse (runRemoteSide remoteside) DATA_PRESENT $ \resp ->
protoerrhandler (const (relayPUTRecord k remoteside) >> requestcomplete) $
client $ net $ sendMessage resp
handlePut_DATA_PRESENT _ _ _ = protoerr
-- The associated file received from the P2P protocol
-- is relative to the top of the git repository. But this process
-- may be running with a different cwd.