Only indicate that we're done with the bytestring once it all gets written.
Otherwise, the end of it may get garbage collected before we can process
it, leading to a hang.
This seems to have been introduced in commit
cdc4bd7443a4921dd0573a0babedc51c1d62f918. Which oddly was trying to fix a
very similar problem, but specific to a cluster node. In that commit,
things got out of order, with it signaling it was done with the bytestring
before it has written all of it to the file.
My test case for this bug is a directory special remote
with a file being sent to it via a proxy accessed via ssh or http.
The file was 10 mb, and it hung on the last few kb of it not being
received.
I've also tested this fix in the case of proxying to a cluster node
directory special remote over http, which was the case
cdc4bd7443a4921dd0573a0babedc51c1d62f918 was dealing with.
receivetofile iv h n = liftIO receivebytestring >>= \case
Just b -> do
+ n' <- storetofile iv h n (L.toChunks b)
liftIO $ atomically $
putTMVar owaitv ()
`orElse`
readTMVar oclosedv
- n' <- storetofile iv h n (L.toChunks b)
-- Normally all the data is sent in a single
-- lazy bytestring. However, when the special
-- remote is a node in a cluster, a PUT is
and then use the P2P protocol to inform the proxy that the content has
been stored there, which will result in the same git-annex branch state
updates as sending DATA via the proxy.
+ * Fix hang when receiving a large file into a proxied special remote.
-- Joey Hess <id@joeyh.name> Thu, 17 Oct 2024 11:02:17 -0400