コード例 #1
0
 public function processRequest()
 {
     $logs = id(new PhabricatorDaemonLog())->loadAllWhere('`status` != %s ORDER BY id DESC LIMIT 15', 'exit');
     $request = $this->getRequest();
     $user = $request->getUser();
     $daemon_table = new PhabricatorDaemonLogListView();
     $daemon_table->setUser($user);
     $daemon_table->setDaemonLogs($logs);
     $daemon_panel = new AphrontPanelView();
     $daemon_panel->setHeader('Recently Launched Daemons');
     $daemon_panel->appendChild($daemon_table);
     $tasks = id(new PhabricatorWorkerTask())->loadAllWhere('leaseOwner IS NOT NULL');
     $rows = array();
     foreach ($tasks as $task) {
         $rows[] = array($task->getID(), $task->getTaskClass(), $task->getLeaseOwner(), $task->getLeaseExpires() - time(), $task->getFailureCount(), phutil_render_tag('a', array('href' => '/daemon/task/' . $task->getID() . '/', 'class' => 'button small grey'), 'View Task'));
     }
     $leased_table = new AphrontTableView($rows);
     $leased_table->setHeaders(array('ID', 'Class', 'Owner', 'Expires', 'Failures', ''));
     $leased_table->setColumnClasses(array('n', 'wide', '', '', 'n', 'action'));
     $leased_table->setNoDataString('No tasks are leased by workers.');
     $leased_panel = new AphrontPanelView();
     $leased_panel->setHeader('Leased Tasks');
     $leased_panel->appendChild($leased_table);
     $task_table = new PhabricatorWorkerTask();
     $queued = queryfx_all($task_table->establishConnection('r'), 'SELECT taskClass, count(*) N FROM %T GROUP BY taskClass
     ORDER BY N DESC', $task_table->getTableName());
     $rows = array();
     foreach ($queued as $row) {
         $rows[] = array(phutil_escape_html($row['taskClass']), number_format($row['N']));
     }
     $queued_table = new AphrontTableView($rows);
     $queued_table->setHeaders(array('Class', 'Count'));
     $queued_table->setColumnClasses(array('wide', 'n'));
     $queued_table->setNoDataString('Task queue is empty.');
     $queued_panel = new AphrontPanelView();
     $queued_panel->setHeader('Queued Tasks');
     $queued_panel->appendChild($queued_table);
     $cursors = id(new PhabricatorTimelineCursor())->loadAll();
     $rows = array();
     foreach ($cursors as $cursor) {
         $rows[] = array(phutil_escape_html($cursor->getName()), number_format($cursor->getPosition()));
     }
     $cursor_table = new AphrontTableView($rows);
     $cursor_table->setHeaders(array('Name', 'Position'));
     $cursor_table->setColumnClasses(array('wide', 'n'));
     $cursor_table->setNoDataString('No timeline cursors exist.');
     $cursor_panel = new AphrontPanelView();
     $cursor_panel->setHeader('Timeline Cursors');
     $cursor_panel->appendChild($cursor_table);
     $nav = $this->buildSideNavView();
     $nav->selectFilter('');
     $nav->appendChild(array($daemon_panel, $cursor_panel, $queued_panel, $leased_panel));
     return $this->buildApplicationPage($nav, array('title' => 'Console'));
 }
コード例 #2
0
 public function run()
 {
     $lease_ownership_name = $this->getLeaseOwnershipName();
     $task_table = new PhabricatorWorkerTask();
     $taskdata_table = new PhabricatorWorkerTaskData();
     $sleep = 0;
     do {
         $conn_w = $task_table->establishConnection('w');
         queryfx($conn_w, 'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15
       WHERE leaseOwner IS NULL LIMIT 1', $task_table->getTableName(), $lease_ownership_name);
         $rows = $conn_w->getAffectedRows();
         if (!$rows) {
             $rows = queryfx($conn_w, 'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15
         WHERE leaseExpires < UNIX_TIMESTAMP() LIMIT 1', $task_table->getTableName(), $lease_ownership_name);
             $rows = $conn_w->getAffectedRows();
         }
         if ($rows) {
             $data = queryfx_all($conn_w, 'SELECT task.*, taskdata.data _taskData, UNIX_TIMESTAMP() _serverTime
         FROM %T task LEFT JOIN %T taskdata
           ON taskdata.id = task.dataID
         WHERE leaseOwner = %s AND leaseExpires > UNIX_TIMESTAMP()
         LIMIT 1', $task_table->getTableName(), $taskdata_table->getTableName(), $lease_ownership_name);
             $tasks = $task_table->loadAllFromArray($data);
             $tasks = mpull($tasks, null, 'getID');
             $task_data = array();
             foreach ($data as $row) {
                 $tasks[$row['id']]->setServerTime($row['_serverTime']);
                 if ($row['_taskData']) {
                     $task_data[$row['id']] = json_decode($row['_taskData'], true);
                 } else {
                     $task_data[$row['id']] = null;
                 }
             }
             foreach ($tasks as $task) {
                 // TODO: We should detect if we acquired a task with an expired lease
                 // and log about it / bump up failure count.
                 // TODO: We should detect if we acquired a task with an excessive
                 // failure count and fail it permanently.
                 $data = idx($task_data, $task->getID());
                 $class = $task->getTaskClass();
                 try {
                     PhutilSymbolLoader::loadClass($class);
                     if (!is_subclass_of($class, 'PhabricatorWorker')) {
                         throw new Exception("Task class '{$class}' does not extend PhabricatorWorker.");
                     }
                     $worker = newv($class, array($data));
                     $lease = $worker->getRequiredLeaseTime();
                     if ($lease !== null) {
                         $task->setLeaseDuration($lease);
                     }
                     $worker->executeTask();
                     $task->delete();
                     if ($data !== null) {
                         queryfx($conn_w, 'DELETE FROM %T WHERE id = %d', $taskdata_table->getTableName(), $task->getDataID());
                     }
                 } catch (Exception $ex) {
                     $task->setFailureCount($task->getFailureCount() + 1);
                     $task->save();
                     throw $ex;
                 }
             }
             $sleep = 0;
         } else {
             $sleep = min($sleep + 1, 30);
         }
         $this->sleep($sleep);
     } while (true);
 }