Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/ssh/DiffusionGitUploadPackSSHWorkflow.php
Show First 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | while (true) { | ||||
$this->didBeginRequest(); | $this->didBeginRequest(); | ||||
$err = $this->newPassthruCommand() | $err = $this->newPassthruCommand() | ||||
->setIOChannel($this->getIOChannel()) | ->setIOChannel($this->getIOChannel()) | ||||
->setCommandChannelFromExecFuture($future) | ->setCommandChannelFromExecFuture($future) | ||||
->execute(); | ->execute(); | ||||
$err = 1; | |||||
// TODO: Currently, when proxying, we do not write an event log on the | // TODO: Currently, when proxying, we do not write an event log on the | ||||
// proxy. Perhaps we should write a "proxy log". This is not very useful | // proxy. Perhaps we should write a "proxy log". This is not very useful | ||||
// for statistics or auditing, but could be useful for diagnostics. | // for statistics or auditing, but could be useful for diagnostics. | ||||
// Marking the proxy logs as proxied (and recording devicePHID on all | // Marking the proxy logs as proxied (and recording devicePHID on all | ||||
// logs) would make differentiating between these use cases easier. | // logs) would make differentiating between these use cases easier. | ||||
if (!$err) { | if (!$err) { | ||||
$this->waitForGitClient(); | $this->waitForGitClient(); | ||||
return $err; | return $err; | ||||
} | } | ||||
// Throw away this service: the request failed and we're treating the | // Throw away this service: the request failed and we're treating the | ||||
// failure as persistent, so we don't want to retry another request to | // failure as persistent, so we don't want to retry another request to | ||||
// the same host. | // the same host. | ||||
array_shift($refs); | array_shift($refs); | ||||
// Check if we have more services we can try. If we do, we'll make an | $should_retry = $this->shouldRetryRequest($refs); | ||||
// effort to fall back to them below. If not, we can't do anything to | |||||
// recover so just bail out. | |||||
if (!$refs) { | |||||
return $err; | |||||
} | |||||
$should_retry = $this->shouldRetryRequest(); | |||||
if (!$should_retry) { | if (!$should_retry) { | ||||
return $err; | return $err; | ||||
} | } | ||||
// If we haven't bailed out yet, we'll retry the request with the next | // If we haven't bailed out yet, we'll retry the request with the next | ||||
// service. | // service. | ||||
} | } | ||||
throw new Exception(pht('Reached an unreachable place.')); | throw new Exception(pht('Reached an unreachable place.')); | ||||
} | } | ||||
private function didBeginRequest() { | private function didBeginRequest() { | ||||
$this->requestAttempts++; | $this->requestAttempts++; | ||||
return $this; | return $this; | ||||
} | } | ||||
private function shouldRetryRequest() { | private function shouldRetryRequest(array $remaining_refs) { | ||||
$this->requestFailures++; | $this->requestFailures++; | ||||
if ($this->requestFailures > $this->requestAttempts) { | if ($this->requestFailures > $this->requestAttempts) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
"Workflow has recorded more failures than attempts; there is a ". | "Workflow has recorded more failures than attempts; there is a ". | ||||
"missing call to \"didBeginRequest()\".\n")); | "missing call to \"didBeginRequest()\".\n")); | ||||
} | } | ||||
$max_failures = 3; | if (!$remaining_refs) { | ||||
if ($this->requestFailures >= $max_failures) { | |||||
$this->writeClusterEngineLogMessage( | $this->writeClusterEngineLogMessage( | ||||
pht( | pht( | ||||
"# Reached maximum number of retry attempts, giving up.\n")); | "# All available services failed to serve the request, ". | ||||
"giving up.\n")); | |||||
return false; | return false; | ||||
} | } | ||||
$read_len = $this->getIOBytesRead(); | $read_len = $this->getIOBytesRead(); | ||||
if ($read_len) { | if ($read_len) { | ||||
$this->writeClusterEngineLogMessage( | $this->writeClusterEngineLogMessage( | ||||
pht( | pht( | ||||
"# Client already read from service (%s bytes), unable to retry.\n", | "# Client already read from service (%s bytes), unable to retry.\n", | ||||
Show All 9 Lines | if ($write_len) { | ||||
new PhutilNumber($write_len))); | new PhutilNumber($write_len))); | ||||
return false; | return false; | ||||
} | } | ||||
$this->writeClusterEngineLogMessage( | $this->writeClusterEngineLogMessage( | ||||
pht( | pht( | ||||
"# Service request failed, retrying (making attempt %s of %s).\n", | "# Service request failed, retrying (making attempt %s of %s).\n", | ||||
new PhutilNumber($this->requestAttempts + 1), | new PhutilNumber($this->requestAttempts + 1), | ||||
new PhutilNumber($max_failures))); | new PhutilNumber($this->requestAttempts + count($remaining_refs)))); | ||||
return true; | return true; | ||||
} | } | ||||
} | } |