mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-20 05:42:40 +01:00
Wait for the Git client to disconnect before exiting in Git SSH workflows
Summary: Ref T2230. Very rarely, even though we've flushed the connection and sent all the data, we'll close the connection before Git is happy with it and it will flip out with an error like this: fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed This is hard to reproduce because it depends on the order of read/write operations we can't directly control. I only saw it about 2% of the time, by just running `git pull` over and over again. Waiting for Git to close its side of the connection seems to fix it. Test Plan: Ran `git clone` a ton of times without seeing the error again. Ran `git push` a ton of times with new commits. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2230 Differential Revision: https://secure.phabricator.com/D7558
This commit is contained in:
parent
85f505465e
commit
a4e8fd2289
3 changed files with 21 additions and 1 deletions
|
@ -35,6 +35,7 @@ final class DiffusionSSHGitReceivePackWorkflow
|
|||
$repository->writeStatusMessage(
|
||||
PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE,
|
||||
PhabricatorRepositoryStatusMessage::CODE_OKAY);
|
||||
$this->waitForGitClient();
|
||||
}
|
||||
|
||||
return $err;
|
||||
|
|
|
@ -21,10 +21,16 @@ final class DiffusionSSHGitUploadPackWorkflow
|
|||
|
||||
$future = new ExecFuture('git-upload-pack %s', $repository->getLocalPath());
|
||||
|
||||
return $this->newPassthruCommand()
|
||||
$err = $this->newPassthruCommand()
|
||||
->setIOChannel($this->getIOChannel())
|
||||
->setCommandChannelFromExecFuture($future)
|
||||
->execute();
|
||||
|
||||
if (!$err) {
|
||||
$this->waitForGitClient();
|
||||
}
|
||||
|
||||
return $err;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,4 +7,17 @@ abstract class DiffusionSSHGitWorkflow extends DiffusionSSHWorkflow {
|
|||
return parent::writeError($message."\n");
|
||||
}
|
||||
|
||||
protected function waitForGitClient() {
|
||||
$io_channel = $this->getIOChannel();
|
||||
|
||||
// If we don't wait for the client to close the connection, `git` will
|
||||
// consider it an early abort and fail. Sit around until Git is comfortable
|
||||
// that it really received all the data.
|
||||
while ($io_channel->isOpenForReading()) {
|
||||
$io_channel->update();
|
||||
$this->getErrorChannel()->flush();
|
||||
PhutilChannel::waitForAny(array($io_channel));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue