Changeset View
Changeset View
Standalone View
Standalone View
src/future/exec/ExecFuture.php
Show First 20 Lines • Show All 524 Lines • ▼ Show 20 Lines | /* -( Internals )---------------------------------------------------------- */ | ||||
/** | /** | ||||
* Begin or continue command execution. | * Begin or continue command execution. | ||||
* | * | ||||
* @return bool True if future has resolved. | * @return bool True if future has resolved. | ||||
* @task internal | * @task internal | ||||
*/ | */ | ||||
public function isReady() { | public function isReady() { | ||||
// NOTE: We have soft dependencies on PhutilServiceProfiler and | // NOTE: We have a soft dependencies on PhutilErrorTrap here, to avoid | ||||
// PhutilErrorTrap here. These dependencies are soft to avoid the need to | // the need to build it into the Phage agent. Under normal circumstances, | ||||
// build them into the Phage agent. Under normal circumstances, these | // this class are always available. | ||||
// classes are always available. | |||||
if (!$this->pipes) { | if (!$this->pipes) { | ||||
$is_windows = phutil_is_windows(); | $is_windows = phutil_is_windows(); | ||||
// NOTE: See note above about Phage. | |||||
if (class_exists('PhutilServiceProfiler')) { | |||||
$profiler = PhutilServiceProfiler::getInstance(); | |||||
$this->profilerCallID = $profiler->beginServiceCall( | |||||
array( | |||||
'type' => 'exec', | |||||
'command' => phutil_string_cast($this->getCommand()), | |||||
)); | |||||
} | |||||
if (!$this->start) { | if (!$this->start) { | ||||
// We might already have started the timer via initiating resolution. | // We might already have started the timer via initiating resolution. | ||||
$this->start = microtime(true); | $this->start = microtime(true); | ||||
} | } | ||||
$unmasked_command = $this->getCommand(); | $unmasked_command = $this->getCommand(); | ||||
$unmasked_command = $unmasked_command->getUnmaskedString(); | $unmasked_command = $unmasked_command->getUnmaskedString(); | ||||
▲ Show 20 Lines • Show All 279 Lines • ▼ Show 20 Lines | private function closeProcess() { | ||||
if ($this->proc) { | if ($this->proc) { | ||||
@proc_close($this->proc); | @proc_close($this->proc); | ||||
$this->proc = null; | $this->proc = null; | ||||
} | } | ||||
$this->stdin = null; | $this->stdin = null; | ||||
unset($this->windowsStdoutTempFile); | unset($this->windowsStdoutTempFile); | ||||
unset($this->windowsStderrTempFile); | unset($this->windowsStderrTempFile); | ||||
if ($this->profilerCallID !== null) { | |||||
if ($this->hasResult()) { | |||||
$result = $this->getResult(); | |||||
$err = idx($result, 0); | |||||
} else { | |||||
$err = null; | |||||
} | |||||
$profiler = PhutilServiceProfiler::getInstance(); | |||||
$profiler->endServiceCall( | |||||
$this->profilerCallID, | |||||
array( | |||||
'err' => $err, | |||||
)); | |||||
$this->profilerCallID = null; | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Execute `proc_get_status()`, but avoid pitfalls. | * Execute `proc_get_status()`, but avoid pitfalls. | ||||
* | * | ||||
* @return dict Process status. | * @return dict Process status. | ||||
* @task internal | * @task internal | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | while (true) { | ||||
$waited = (microtime(true) - $start); | $waited = (microtime(true) - $start); | ||||
if ($waited > $duration) { | if ($waited > $duration) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
protected function getServiceProfilerStartParameters() { | |||||
return array( | |||||
'type' => 'exec', | |||||
'command' => phutil_string_cast($this->getCommand()), | |||||
); | |||||
} | |||||
protected function getServiceProfilerResultParameters() { | |||||
if ($this->hasResult()) { | |||||
$result = $this->getResult(); | |||||
$err = idx($result, 0); | |||||
} else { | |||||
$err = null; | |||||
} | |||||
return array( | |||||
'err' => $err, | |||||
); | |||||
} | |||||
} | } |