mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-30 10:42:41 +01:00
Use a real Query class to load daemon information
Summary: Ref T3557. This stuff does a bunch of nonsense in the View right now. Instead, do it in a real Query class. Fixes a long-standing bug which prevented "all daemons" from showing more than 3 days' worth of data. Test Plan: Viewed `/daemon/`, viewed "All Daemons". Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3557 Differential Revision: https://secure.phabricator.com/D6544
This commit is contained in:
parent
df3f4d5a40
commit
e793a3657a
9 changed files with 173 additions and 84 deletions
|
@ -1019,10 +1019,10 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/PhabricatorDaemonCombinedLogController.php',
|
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/PhabricatorDaemonCombinedLogController.php',
|
||||||
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/PhabricatorDaemonConsoleController.php',
|
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/PhabricatorDaemonConsoleController.php',
|
||||||
'PhabricatorDaemonController' => 'applications/daemon/controller/PhabricatorDaemonController.php',
|
'PhabricatorDaemonController' => 'applications/daemon/controller/PhabricatorDaemonController.php',
|
||||||
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/PhabricatorDaemonDAO.php',
|
'PhabricatorDaemonDAO' => 'applications/daemon/storage/PhabricatorDaemonDAO.php',
|
||||||
'PhabricatorDaemonEventListener' => 'applications/daemon/event/PhabricatorDaemonEventListener.php',
|
'PhabricatorDaemonEventListener' => 'applications/daemon/event/PhabricatorDaemonEventListener.php',
|
||||||
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/PhabricatorDaemonLog.php',
|
'PhabricatorDaemonLog' => 'applications/daemon/storage/PhabricatorDaemonLog.php',
|
||||||
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/PhabricatorDaemonLogEvent.php',
|
'PhabricatorDaemonLogEvent' => 'applications/daemon/storage/PhabricatorDaemonLogEvent.php',
|
||||||
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/PhabricatorDaemonLogEventsView.php',
|
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/PhabricatorDaemonLogEventsView.php',
|
||||||
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/PhabricatorDaemonLogListController.php',
|
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/PhabricatorDaemonLogListController.php',
|
||||||
'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php',
|
'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php',
|
||||||
|
@ -3023,11 +3023,16 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDaemonController' => 'PhabricatorController',
|
'PhabricatorDaemonController' => 'PhabricatorController',
|
||||||
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorDaemonEventListener' => 'PhutilEventListener',
|
'PhabricatorDaemonEventListener' => 'PhutilEventListener',
|
||||||
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
|
'PhabricatorDaemonLog' =>
|
||||||
|
array(
|
||||||
|
0 => 'PhabricatorDaemonDAO',
|
||||||
|
1 => 'PhabricatorPolicyInterface',
|
||||||
|
),
|
||||||
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
|
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
|
||||||
'PhabricatorDaemonLogEventsView' => 'AphrontView',
|
'PhabricatorDaemonLogEventsView' => 'AphrontView',
|
||||||
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonLogListView' => 'AphrontView',
|
'PhabricatorDaemonLogListView' => 'AphrontView',
|
||||||
|
'PhabricatorDaemonLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonManagementDebugWorkflow' => 'PhabricatorDaemonManagementWorkflow',
|
'PhabricatorDaemonManagementDebugWorkflow' => 'PhabricatorDaemonManagementWorkflow',
|
||||||
'PhabricatorDaemonManagementLaunchWorkflow' => 'PhabricatorDaemonManagementWorkflow',
|
'PhabricatorDaemonManagementLaunchWorkflow' => 'PhabricatorDaemonManagementWorkflow',
|
||||||
|
|
|
@ -57,13 +57,13 @@ final class PhabricatorDaemonConsoleController
|
||||||
$completed_panel->appendChild($completed_table);
|
$completed_panel->appendChild($completed_table);
|
||||||
$completed_panel->setNoBackground();
|
$completed_panel->setNoBackground();
|
||||||
|
|
||||||
$logs = id(new PhabricatorDaemonLog())->loadAllWhere(
|
$logs = id(new PhabricatorDaemonLogQuery())
|
||||||
'`status` = %s ORDER BY id DESC',
|
->setViewer($user)
|
||||||
'run');
|
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||||
|
->execute();
|
||||||
|
|
||||||
$daemon_header = id(new PhabricatorHeaderView())
|
$daemon_header = id(new PhabricatorHeaderView())
|
||||||
->setHeader(pht('Recent Daemons'));
|
->setHeader(pht('Active Daemons'));
|
||||||
|
|
||||||
$daemon_table = new PhabricatorDaemonLogListView();
|
$daemon_table = new PhabricatorDaemonLogListView();
|
||||||
$daemon_table->setUser($user);
|
$daemon_table->setUser($user);
|
||||||
|
|
|
@ -5,20 +5,14 @@ final class PhabricatorDaemonLogListController
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
$pager = new AphrontPagerView();
|
$pager = new AphrontCursorPagerView();
|
||||||
$pager->setOffset($request->getInt('page'));
|
$pager->readFromRequest($request);
|
||||||
|
|
||||||
$clause = '1 = 1';
|
$logs = id(new PhabricatorDaemonLogQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
$logs = id(new PhabricatorDaemonLog())->loadAllWhere(
|
->executeWithCursorPager($pager);
|
||||||
'%Q ORDER BY id DESC LIMIT %d, %d',
|
|
||||||
$clause,
|
|
||||||
$pager->getOffset(),
|
|
||||||
$pager->getPageSize() + 1);
|
|
||||||
|
|
||||||
$logs = $pager->sliceResults($logs);
|
|
||||||
$pager->setURI($request->getRequestURI(), 'page');
|
|
||||||
|
|
||||||
$daemon_table = new PhabricatorDaemonLogListView();
|
$daemon_table = new PhabricatorDaemonLogListView();
|
||||||
$daemon_table->setUser($request->getUser());
|
$daemon_table->setUser($request->getUser());
|
||||||
|
@ -33,6 +27,7 @@ final class PhabricatorDaemonLogListController
|
||||||
$nav->selectFilter('log');
|
$nav->selectFilter('log');
|
||||||
$nav->setCrumbs($crumbs);
|
$nav->setCrumbs($crumbs);
|
||||||
$nav->appendChild($daemon_table);
|
$nav->appendChild($daemon_table);
|
||||||
|
$nav->appendChild($pager);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
$nav,
|
$nav,
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorDaemonLogQuery {
|
final class PhabricatorDaemonLogQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
const STATUS_ALL = 'status-all';
|
||||||
|
const STATUS_ALIVE = 'status-alive';
|
||||||
|
|
||||||
|
private $status = self::STATUS_ALL;
|
||||||
|
|
||||||
public static function getTimeUntilUnknown() {
|
public static function getTimeUntilUnknown() {
|
||||||
return 3 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
|
return 3 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
|
||||||
|
@ -10,4 +16,104 @@ final class PhabricatorDaemonLogQuery {
|
||||||
return 30 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
|
return 30 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withStatus($status) {
|
||||||
|
$this->status = $status;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadPage() {
|
||||||
|
$table = new PhabricatorDaemonLog();
|
||||||
|
$conn_r = $table->establishConnection('r');
|
||||||
|
|
||||||
|
$data = queryfx_all(
|
||||||
|
$conn_r,
|
||||||
|
'SELECT * FROM %T %Q %Q %Q',
|
||||||
|
$table->getTableName(),
|
||||||
|
$this->buildWhereClause($conn_r),
|
||||||
|
$this->buildOrderClause($conn_r),
|
||||||
|
$this->buildLimitClause($conn_r));
|
||||||
|
|
||||||
|
return $table->loadAllFromArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function willFilterPage(array $daemons) {
|
||||||
|
$unknown_delay = PhabricatorDaemonLogQuery::getTimeUntilUnknown();
|
||||||
|
$dead_delay = PhabricatorDaemonLogQuery::getTimeUntilDead();
|
||||||
|
|
||||||
|
$status_running = PhabricatorDaemonLog::STATUS_RUNNING;
|
||||||
|
$status_unknown = PhabricatorDaemonLog::STATUS_UNKNOWN;
|
||||||
|
$status_wait = PhabricatorDaemonLog::STATUS_WAIT;
|
||||||
|
$status_exited = PhabricatorDaemonLog::STATUS_EXITED;
|
||||||
|
$status_dead = PhabricatorDaemonLog::STATUS_DEAD;
|
||||||
|
|
||||||
|
$filter = array_fuse($this->getStatusConstants());
|
||||||
|
|
||||||
|
foreach ($daemons as $key => $daemon) {
|
||||||
|
$status = $daemon->getStatus();
|
||||||
|
$seen = $daemon->getDateModified();
|
||||||
|
|
||||||
|
$is_running = ($status == $status_running) ||
|
||||||
|
($status == $status_wait);
|
||||||
|
|
||||||
|
// If we haven't seen the daemon recently, downgrade its status to
|
||||||
|
// unknown.
|
||||||
|
$unknown_time = ($seen + $unknown_delay);
|
||||||
|
if ($is_running && ($unknown_time < time())) {
|
||||||
|
$status = $status_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the daemon hasn't been seen in quite a while, assume it is dead.
|
||||||
|
$dead_time = ($seen + $dead_delay);
|
||||||
|
if (($status == $status_unknown) && ($dead_time < time())) {
|
||||||
|
$status = $status_dead;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we changed the daemon's status, update it.
|
||||||
|
if ($status != $daemon->getStatus()) {
|
||||||
|
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
$daemon->setStatus($status)->save();
|
||||||
|
unset($guard);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the daemon no longer matches the filter, get rid of it.
|
||||||
|
if ($filter) {
|
||||||
|
if (empty($filter[$daemon->getStatus()])) {
|
||||||
|
unset($daemons[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $daemons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||||
|
$where = array();
|
||||||
|
|
||||||
|
if ($this->getStatusConstants()) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'status IN (%Ls)',
|
||||||
|
$this->getStatusConstants());
|
||||||
|
}
|
||||||
|
|
||||||
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
return $this->formatWhereClause($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getStatusConstants() {
|
||||||
|
$status = $this->status;
|
||||||
|
switch ($status) {
|
||||||
|
case self::STATUS_ALL:
|
||||||
|
return array();
|
||||||
|
case self::STATUS_ALIVE:
|
||||||
|
return array(
|
||||||
|
PhabricatorDaemonLog::STATUS_UNKNOWN,
|
||||||
|
PhabricatorDaemonLog::STATUS_RUNNING,
|
||||||
|
PhabricatorDaemonLog::STATUS_WAIT,
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new Exception("Unknown status '{$status}'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
44
src/applications/daemon/storage/PhabricatorDaemonLog.php
Normal file
44
src/applications/daemon/storage/PhabricatorDaemonLog.php
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorDaemonLog extends PhabricatorDaemonDAO
|
||||||
|
implements PhabricatorPolicyInterface {
|
||||||
|
|
||||||
|
const STATUS_UNKNOWN = 'unknown';
|
||||||
|
const STATUS_RUNNING = 'run';
|
||||||
|
const STATUS_DEAD = 'dead';
|
||||||
|
const STATUS_WAIT = 'wait';
|
||||||
|
const STATUS_EXITED = 'exit';
|
||||||
|
|
||||||
|
protected $daemon;
|
||||||
|
protected $host;
|
||||||
|
protected $pid;
|
||||||
|
protected $argv;
|
||||||
|
protected $status;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'argv' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
return PhabricatorPolicies::POLICY_ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,43 +19,6 @@ final class PhabricatorDaemonLogListView extends AphrontView {
|
||||||
|
|
||||||
$list = id(new PhabricatorObjectItemListView());
|
$list = id(new PhabricatorObjectItemListView());
|
||||||
foreach ($this->daemonLogs as $log) {
|
foreach ($this->daemonLogs as $log) {
|
||||||
|
|
||||||
// TODO: VVV Move this stuff to a Query class. VVV
|
|
||||||
|
|
||||||
$expect_heartbeat = PhabricatorDaemonLogQuery::getTimeUntilUnknown();
|
|
||||||
$assume_dead = PhabricatorDaemonLogQuery::getTimeUntilDead();
|
|
||||||
|
|
||||||
$status_running = PhabricatorDaemonLog::STATUS_RUNNING;
|
|
||||||
$status_unknown = PhabricatorDaemonLog::STATUS_UNKNOWN;
|
|
||||||
$status_wait = PhabricatorDaemonLog::STATUS_WAIT;
|
|
||||||
$status_exited = PhabricatorDaemonLog::STATUS_EXITED;
|
|
||||||
$status_dead = PhabricatorDaemonLog::STATUS_DEAD;
|
|
||||||
|
|
||||||
$status = $log->getStatus();
|
|
||||||
$heartbeat_timeout = $log->getDateModified() + $expect_heartbeat;
|
|
||||||
if ($status == $status_running && $heartbeat_timeout < time()) {
|
|
||||||
$status = $status_unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($status == $status_unknown && $assume_dead < time()) {
|
|
||||||
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
||||||
$log->setStatus($status_dead)->save();
|
|
||||||
unset($guard);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($status != $status_running &&
|
|
||||||
$log->getDateModified() + (3 * 86400) < time()) {
|
|
||||||
// Don't show rows that haven't been running for more than
|
|
||||||
// three days. We should probably prune these out of the
|
|
||||||
// DB similar to the code above, but we don't need to be
|
|
||||||
// conservative and do it only on the same host
|
|
||||||
|
|
||||||
// TODO: This should not apply to the "all daemons" view!
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: ^^^^ ALL THAT STUFF ^^^
|
|
||||||
|
|
||||||
$id = $log->getID();
|
$id = $log->getID();
|
||||||
$epoch = $log->getDateCreated();
|
$epoch = $log->getDateCreated();
|
||||||
|
|
||||||
|
@ -65,6 +28,7 @@ final class PhabricatorDaemonLogListView extends AphrontView {
|
||||||
->setHref("/daemon/log/{$id}/")
|
->setHref("/daemon/log/{$id}/")
|
||||||
->addIcon('none', phabricator_datetime($epoch, $this->user));
|
->addIcon('none', phabricator_datetime($epoch, $this->user));
|
||||||
|
|
||||||
|
$status = $log->getStatus();
|
||||||
switch ($status) {
|
switch ($status) {
|
||||||
case PhabricatorDaemonLog::STATUS_RUNNING:
|
case PhabricatorDaemonLog::STATUS_RUNNING:
|
||||||
$item->setBarColor('green');
|
$item->setBarColor('green');
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorDaemonLog extends PhabricatorDaemonDAO {
|
|
||||||
|
|
||||||
const STATUS_UNKNOWN = 'unknown';
|
|
||||||
const STATUS_RUNNING = 'run';
|
|
||||||
const STATUS_DEAD = 'dead';
|
|
||||||
const STATUS_WAIT = 'wait';
|
|
||||||
const STATUS_EXITED = 'exit';
|
|
||||||
|
|
||||||
protected $daemon;
|
|
||||||
protected $host;
|
|
||||||
protected $pid;
|
|
||||||
protected $argv;
|
|
||||||
protected $status;
|
|
||||||
|
|
||||||
public function getConfiguration() {
|
|
||||||
return array(
|
|
||||||
self::CONFIG_SERIALIZATION => array(
|
|
||||||
'argv' => self::SERIALIZATION_JSON,
|
|
||||||
),
|
|
||||||
) + parent::getConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue