summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-11-11 13:38:28 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-11-11 13:38:28 -0400
commit2aa6505378c3789da0cf78c784467c67fd9d593c (patch)
tree3799c0930f4ac230d74f8ec55f2ebe017f7a73ce
parent2fd3fde8b28fd5e188090ecd975122d6c3984396 (diff)
add 120 second timeout when waiting for XMPP packets
-rw-r--r--Assistant/XMPP/Git.hs49
1 files changed, 39 insertions, 10 deletions
diff --git a/Assistant/XMPP/Git.hs b/Assistant/XMPP/Git.hs
index 6aa280ec7..f03b32439 100644
--- a/Assistant/XMPP/Git.hs
+++ b/Assistant/XMPP/Git.hs
@@ -25,6 +25,7 @@ import qualified Git.Branch
import Locations.UserConfig
import qualified Types.Remote as Remote
import Utility.FileMode
+import Utility.ThreadScheduler
import Network.Protocol.XMPP
import qualified Data.Text as T
@@ -118,15 +119,23 @@ xmppPush cid gitpush = runPush (SendPushRunning cid) handleDeferred $ do
then liftIO $ killThread =<< myThreadId
else sendNetMessage $ Pushing cid $ SendPackOutput b
fromxmpp outh controlh = forever $ do
- m <- waitNetPushMessage
+ m <- runTimeout xmppTimeout <~> waitNetPushMessage
case m of
- (Pushing _ (ReceivePackOutput b)) ->
+ (Right (Pushing _ (ReceivePackOutput b))) ->
liftIO $ writeChunk outh b
- (Pushing _ (ReceivePackDone exitcode)) ->
+ (Right (Pushing _ (ReceivePackDone exitcode))) ->
liftIO $ do
hPrint controlh exitcode
hFlush controlh
- _ -> noop
+ (Right _) -> noop
+ (Left _) -> do
+ debug ["timeout waiting for git receive-pack output via XMPP"]
+ -- Send a synthetic exit code to git-annex
+ -- xmppgit, which will exit and cause git push
+ -- to die.
+ liftIO $ do
+ hPrint controlh (ExitFailure 1)
+ hFlush controlh
installwrapper tmpdir = liftIO $ do
createDirectoryIfMissing True tmpdir
let wrapper = tmpdir </> "git-remote-xmpp"
@@ -211,11 +220,18 @@ xmppReceivePack cid = runPush (ReceivePushRunning cid) handleDeferred $ do
sendNetMessage $ Pushing cid $ ReceivePackOutput b
relaytoxmpp outh
relayfromxmpp inh = forever $ do
- m <- waitNetPushMessage
+ m <- runTimeout xmppTimeout <~> waitNetPushMessage
case m of
- (Pushing _ (SendPackOutput b)) ->
+ (Right (Pushing _ (SendPackOutput b))) ->
liftIO $ writeChunk inh b
- _ -> noop
+ (Right _) -> noop
+ (Left _) -> do
+ debug ["timeout waiting for git send-pack output via XMPP"]
+ -- closing the handle will make
+ -- git receive-pack exit
+ liftIO $ do
+ hClose inh
+ killThread =<< myThreadId
xmppRemotes :: ClientID -> Assistant [Remote]
xmppRemotes cid = case baseJID <$> parseJID cid of
@@ -257,10 +273,23 @@ handlePushMessage _ = noop
handleDeferred :: NetMessage -> Assistant ()
handleDeferred = handlePushMessage
-chunkSize :: Int
-chunkSize = 4096
-
writeChunk :: Handle -> B.ByteString -> IO ()
writeChunk h b = do
B.hPut h b
hFlush h
+
+{- Largest chunk of data to send in a single XMPP message. -}
+chunkSize :: Int
+chunkSize = 4096
+
+{- How long to wait for an expected message before assuming the other side
+ - has gone away and canceling a push.
+ -
+ - This needs to be long enough to allow a message of up to 2+ times
+ - chunkSize to propigate up to a XMPP server, perhaps across to another
+ - server, and back down to us. On the other hand, other XMPP pushes can be
+ - delayed for running until the timeout is reached, so it should not be
+ - excessive.
+ -}
+xmppTimeout :: Seconds
+xmppTimeout = Seconds 120