Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/daemon/PhutilDaemonHandle.php
Show All 10 Lines | final class PhutilDaemonHandle extends Phobject { | ||||
private $pool; | private $pool; | ||||
private $properties; | private $properties; | ||||
private $future; | private $future; | ||||
private $argv; | private $argv; | ||||
private $restartAt; | private $restartAt; | ||||
private $busyEpoch; | private $busyEpoch; | ||||
private $pid; | |||||
private $daemonID; | private $daemonID; | ||||
private $deadline; | private $deadline; | ||||
private $heartbeat; | private $heartbeat; | ||||
private $stdoutBuffer; | private $stdoutBuffer; | ||||
private $shouldRestart = true; | private $shouldRestart = true; | ||||
private $shouldShutdown; | private $shouldShutdown; | ||||
private $hibernating = false; | private $hibernating = false; | ||||
private $shouldSendExitEvent = false; | private $shouldSendExitEvent = false; | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | $this->dispatchEvent( | ||||
'argv' => $this->getCommandLineArguments(), | 'argv' => $this->getCommandLineArguments(), | ||||
'explicitArgv' => $this->getDaemonArguments(), | 'explicitArgv' => $this->getDaemonArguments(), | ||||
)); | )); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function isRunning() { | public function isRunning() { | ||||
return (bool)$this->future; | return (bool)$this->getFuture(); | ||||
} | } | ||||
public function isHibernating() { | public function isHibernating() { | ||||
return | return | ||||
!$this->isRunning() && | !$this->isRunning() && | ||||
!$this->isDone() && | !$this->isDone() && | ||||
$this->hibernating; | $this->hibernating; | ||||
} | } | ||||
Show All 13 Lines | public function wakeFromHibernation() { | ||||
return $this; | return $this; | ||||
} | } | ||||
public function isDone() { | public function isDone() { | ||||
return (!$this->shouldRestart && !$this->isRunning()); | return (!$this->shouldRestart && !$this->isRunning()); | ||||
} | } | ||||
public function getFuture() { | |||||
return $this->future; | |||||
} | |||||
public function update() { | public function update() { | ||||
if (!$this->isRunning()) { | if (!$this->isRunning()) { | ||||
if (!$this->shouldRestart) { | if (!$this->shouldRestart) { | ||||
return; | return; | ||||
} | } | ||||
if (!$this->restartAt || (time() < $this->restartAt)) { | if (!$this->restartAt || (time() < $this->restartAt)) { | ||||
return; | return; | ||||
} | } | ||||
if ($this->shouldShutdown) { | if ($this->shouldShutdown) { | ||||
return; | return; | ||||
} | } | ||||
$this->startDaemonProcess(); | $this->startDaemonProcess(); | ||||
} | } | ||||
$future = $this->future; | $future = $this->getFuture(); | ||||
$result = null; | $result = null; | ||||
if ($future->isReady()) { | $caught = null; | ||||
if ($future->canResolve()) { | |||||
jmeador: `canResolve` doesn't seem to exist anywhere in the codebase... but my daemons work fine. What… | |||||
$this->future = null; | |||||
try { | |||||
$result = $future->resolve(); | $result = $future->resolve(); | ||||
} catch (Exception $ex) { | |||||
$caught = $ex; | |||||
} catch (Throwable $ex) { | |||||
$caught = $ex; | |||||
} | |||||
} | } | ||||
list($stdout, $stderr) = $future->read(); | list($stdout, $stderr) = $future->read(); | ||||
$future->discardBuffers(); | $future->discardBuffers(); | ||||
if (strlen($stdout)) { | if (strlen($stdout)) { | ||||
$this->didReadStdout($stdout); | $this->didReadStdout($stdout); | ||||
} | } | ||||
$stderr = trim($stderr); | $stderr = trim($stderr); | ||||
if (strlen($stderr)) { | if (strlen($stderr)) { | ||||
foreach (phutil_split_lines($stderr, false) as $line) { | foreach (phutil_split_lines($stderr, false) as $line) { | ||||
$this->logMessage('STDE', $line); | $this->logMessage('STDE', $line); | ||||
} | } | ||||
} | } | ||||
if ($result !== null) { | if ($result !== null || $caught !== null) { | ||||
if ($caught) { | |||||
$message = pht( | |||||
'Process failed with exception: %s', | |||||
$caught->getMessage()); | |||||
$this->logMessage('FAIL', $message); | |||||
} else { | |||||
list($err) = $result; | list($err) = $result; | ||||
if ($err) { | if ($err) { | ||||
$this->logMessage('FAIL', pht('Process exited with error %s.', $err)); | $this->logMessage('FAIL', pht('Process exited with error %s.', $err)); | ||||
} else { | } else { | ||||
$this->logMessage('DONE', pht('Process exited normally.')); | $this->logMessage('DONE', pht('Process exited normally.')); | ||||
} | } | ||||
} | |||||
$this->future = null; | |||||
if ($this->shouldShutdown) { | if ($this->shouldShutdown) { | ||||
$this->restartAt = null; | $this->restartAt = null; | ||||
} else { | } else { | ||||
$this->scheduleRestart(); | $this->scheduleRestart(); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | final class PhutilDaemonHandle extends Phobject { | ||||
private function generateDaemonID() { | private function generateDaemonID() { | ||||
return substr(getmypid().':'.Filesystem::readRandomCharacters(12), 0, 12); | return substr(getmypid().':'.Filesystem::readRandomCharacters(12), 0, 12); | ||||
} | } | ||||
public function getDaemonID() { | public function getDaemonID() { | ||||
return $this->daemonID; | return $this->daemonID; | ||||
} | } | ||||
public function getPID() { | private function getFuture() { | ||||
return $this->pid; | return $this->future; | ||||
} | |||||
private function getPID() { | |||||
$future = $this->getFuture(); | |||||
if (!$future) { | |||||
return null; | |||||
} | |||||
if (!$future->hasPID()) { | |||||
return null; | |||||
} | |||||
return $future->getPID(); | |||||
} | } | ||||
private function getCaptureBufferSize() { | private function getCaptureBufferSize() { | ||||
return 65535; | return 65535; | ||||
} | } | ||||
private function getRequiredHeartbeatFrequency() { | private function getRequiredHeartbeatFrequency() { | ||||
return 86400; | return 86400; | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | final class PhutilDaemonHandle extends Phobject { | ||||
private function startDaemonProcess() { | private function startDaemonProcess() { | ||||
$this->logMessage('INIT', pht('Starting process.')); | $this->logMessage('INIT', pht('Starting process.')); | ||||
$this->deadline = time() + $this->getRequiredHeartbeatFrequency(); | $this->deadline = time() + $this->getRequiredHeartbeatFrequency(); | ||||
$this->heartbeat = time() + self::getHeartbeatEventFrequency(); | $this->heartbeat = time() + self::getHeartbeatEventFrequency(); | ||||
$this->stdoutBuffer = ''; | $this->stdoutBuffer = ''; | ||||
$this->hibernating = false; | $this->hibernating = false; | ||||
$this->future = $this->newExecFuture(); | $future = $this->newExecFuture(); | ||||
$this->future->start(); | $this->future = $future; | ||||
$this->pid = $this->future->getPID(); | $pool = $this->getDaemonPool(); | ||||
$overseer = $pool->getOverseer(); | |||||
$overseer->addFutureToPool($future); | |||||
} | } | ||||
private function didReadStdout($data) { | private function didReadStdout($data) { | ||||
$this->stdoutBuffer .= $data; | $this->stdoutBuffer .= $data; | ||||
while (true) { | while (true) { | ||||
$pos = strpos($this->stdoutBuffer, "\n"); | $pos = strpos($this->stdoutBuffer, "\n"); | ||||
if ($pos === false) { | if ($pos === false) { | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 153 Lines • Show Last 20 Lines |
canResolve doesn't seem to exist anywhere in the codebase... but my daemons work fine. What gives?