support DATA-PRESENT in the p2p protocol proxy
authorJoey Hess <joeyh@joeyh.name>
Tue, 29 Oct 2024 18:20:07 +0000 (14:20 -0400)
committerJoey Hess <joeyh@joeyh.name>
Tue, 29 Oct 2024 18:44:23 +0000 (14:44 -0400)
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.

P2P/Proxy.hs

index fc3a5ad0946b55276dc43cd69fbc126f7c802435..3519fa64ed549454c0e6b63d993e520ff458c614 100644 (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,8 +564,8 @@ 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
                -- on the remote's offset.
@@ -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
@@ -671,6 +675,23 @@ proxyRequest proxydone proxyparams requestcomplete requestmessage protoerrhandle
                                                us
                                                        | 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