protected function collectGarbage()
 {
     $table = new HeraldTranscript();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'UPDATE %T SET
       objectTranscript     = "",
       ruleTranscripts      = "",
       conditionTranscripts = "",
       applyTranscripts     = "",
       garbageCollected     = 1
     WHERE garbageCollected = 0 AND time < %d
     LIMIT 100', $table->getTableName(), $this->getGarbageEpoch());
     return $conn_w->getAffectedRows() == 100;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     // Get one page of data together with the pager.
     // Pull these objects manually since the serialized fields are gigantic.
     $transcript = new HeraldTranscript();
     $conn_r = $transcript->establishConnection('r');
     $phid = $request->getStr('phid');
     $where_clause = '';
     if ($phid) {
         $where_clause = qsprintf($conn_r, 'WHERE objectPHID = %s', $phid);
     }
     $pager = new AphrontPagerView();
     $pager->setOffset($request->getInt('offset'));
     $pager->setURI($request->getRequestURI(), 'offset');
     $limit_clause = qsprintf($conn_r, 'LIMIT %d, %d', $pager->getOffset(), $pager->getPageSize() + 1);
     $data = queryfx_all($conn_r, 'SELECT id, objectPHID, time, duration, dryRun FROM %T
     %Q
     ORDER BY id DESC
     %Q', $transcript->getTableName(), $where_clause, $limit_clause);
     $data = $pager->sliceResults($data);
     // Render the table.
     $handles = array();
     if ($data) {
         $phids = ipull($data, 'objectPHID', 'objectPHID');
         $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     }
     $rows = array();
     foreach ($data as $xscript) {
         $rows[] = array(phabricator_date($xscript['time'], $user), phabricator_time($xscript['time'], $user), $handles[$xscript['objectPHID']]->renderLink(), $xscript['dryRun'] ? 'Yes' : '', number_format((int) (1000 * $xscript['duration'])) . ' ms', phutil_render_tag('a', array('href' => '/herald/transcript/' . $xscript['id'] . '/', 'class' => 'button small grey'), 'View Transcript'));
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Date', 'Time', 'Object', 'Dry Run', 'Duration', 'View'));
     $table->setColumnClasses(array('', 'right', 'wide wrap', '', '', 'action'));
     // Render the whole page.
     $panel = new AphrontPanelView();
     $panel->setHeader('Herald Transcripts');
     $panel->appendChild($table);
     $panel->appendChild($pager);
     $nav = $this->renderNav();
     $nav->selectFilter('transcript');
     $nav->appendChild($panel);
     return $this->buildStandardPageResponse($nav, array('title' => 'Herald Transcripts', 'tab' => 'transcripts'));
 }
 public function collectGarbage()
 {
     $ttl = PhabricatorEnv::getEnvConfig('gcdaemon.ttl.herald-transcripts');
     if ($ttl <= 0) {
         return false;
     }
     $table = new HeraldTranscript();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'UPDATE %T SET
       objectTranscript     = "",
       ruleTranscripts      = "",
       conditionTranscripts = "",
       applyTranscripts     = "",
       garbageCollected     = 1
     WHERE garbageCollected = 0 AND time < %d
     LIMIT 100', $table->getTableName(), time() - $ttl);
     return $conn_w->getAffectedRows() == 100;
 }
 protected function loadPage()
 {
     $transcript = new HeraldTranscript();
     $conn_r = $transcript->establishConnection('r');
     // NOTE: Transcripts include a potentially enormous amount of serialized
     // data, so we're loading only some of the fields here if the caller asked
     // for partial records.
     if ($this->needPartialRecords) {
         $fields = implode(', ', array('id', 'phid', 'objectPHID', 'time', 'duration', 'dryRun', 'host'));
     } else {
         $fields = '*';
     }
     $rows = queryfx_all($conn_r, 'SELECT %Q FROM %T t %Q %Q %Q', $fields, $transcript->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r));
     $transcripts = $transcript->loadAllFromArray($rows);
     if ($this->needPartialRecords) {
         // Make sure nothing tries to write these; they aren't complete.
         foreach ($transcripts as $transcript) {
             $transcript->makeEphemeral();
         }
     }
     return $transcripts;
 }
 private function collectHeraldTranscripts()
 {
     $ttl = PhabricatorEnv::getEnvConfig('gcdaemon.ttl.herald-transcripts');
     if ($ttl <= 0) {
         return 0;
     }
     $table = new HeraldTranscript();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'UPDATE %T SET
       objectTranscript     = "",
       ruleTranscripts      = "",
       conditionTranscripts = "",
       applyTranscripts     = ""
     WHERE `time` < %d AND objectTranscript != ""
     LIMIT 100', $table->getTableName(), time() - $ttl);
     return $conn_w->getAffectedRows();
 }