diff --git a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php index bbd73d2d90..9cbb8db8e9 100644 --- a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php +++ b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php @@ -102,43 +102,58 @@ final class PhabricatorRepositoryPullLocalDaemon $retry_after, array_keys($pullable)); - // Figure out which repositories we need to queue for an update. foreach ($pullable as $id => $repository) { - $monogram = $repository->getMonogram(); + $now = PhabricatorTime::getNow(); + $display_name = $repository->getDisplayName(); if (isset($futures[$id])) { - $this->log(pht('Repository "%s" is currently updating.', $monogram)); + $this->log( + pht( + 'Repository "%s" is currently updating.', + $display_name)); continue; } if (isset($queue[$id])) { - $this->log(pht('Repository "%s" is already queued.', $monogram)); + $this->log( + pht( + 'Repository "%s" is already queued.', + $display_name)); continue; } - $after = idx($retry_after, $id, 0); + $after = idx($retry_after, $id); + if (!$after) { + $smart_wait = $repository->loadUpdateInterval($min_sleep); + $last_update = $this->loadLastUpdate($repository); + + $after = $last_update + $smart_wait; + $retry_after[$id] = $after; + + $this->log( + pht( + 'Scheduling repository "%s" with an update window of %s '. + 'second(s). Last update was %s second(s) ago.', + $display_name, + new PhutilNumber($smart_wait), + new PhutilNumber($now - $last_update))); + } + if ($after > time()) { $this->log( pht( 'Repository "%s" is not due for an update for %s second(s).', - $monogram, - new PhutilNumber($after - time()))); + $display_name, + new PhutilNumber($after - $now))); continue; } - if (!$after) { - $this->log( - pht( - 'Scheduling repository "%s" for an initial update.', - $monogram)); - } else { - $this->log( - pht( - 'Scheduling repository "%s" for an update (%s seconds overdue).', - $monogram, - new PhutilNumber(time() - $after))); - } + $this->log( + pht( + 'Scheduling repository "%s" for an update (%s seconds overdue).', + $display_name, + new PhutilNumber($now - $after))); $queue[$id] = $after; } @@ -157,8 +172,11 @@ final class PhabricatorRepositoryPullLocalDaemon continue; } - $monogram = $repository->getMonogram(); - $this->log(pht('Starting update for repository "%s".', $monogram)); + $display_name = $repository->getDisplayName(); + $this->log( + pht( + 'Starting update for repository "%s".', + $display_name)); unset($queue[$id]); $futures[$id] = $this->buildUpdateFuture( @@ -296,6 +314,32 @@ final class PhabricatorRepositoryPullLocalDaemon } + /** + * @task pull + */ + private function loadLastUpdate(PhabricatorRepository $repository) { + $table = new PhabricatorRepositoryStatusMessage(); + $conn = $table->establishConnection('r'); + + $epoch = queryfx_one( + $conn, + 'SELECT MAX(epoch) last_update FROM %T + WHERE repositoryID = %d + AND statusType IN (%Ls)', + $table->getTableName(), + $repository->getID(), + array( + PhabricatorRepositoryStatusMessage::TYPE_INIT, + PhabricatorRepositoryStatusMessage::TYPE_FETCH, + )); + + if ($epoch) { + return (int)$epoch['last_update']; + } + + return PhabricatorTime::getNow(); + } + /** * @task pull */ @@ -385,9 +429,9 @@ final class PhabricatorRepositoryPullLocalDaemon ExecFuture $future, $min_sleep) { - $monogram = $repository->getMonogram(); + $display_name = $repository->getDisplayName(); - $this->log(pht('Resolving update for "%s".', $monogram)); + $this->log(pht('Resolving update for "%s".', $display_name)); try { list($stdout, $stderr) = $future->resolvex(); @@ -395,17 +439,18 @@ final class PhabricatorRepositoryPullLocalDaemon $proxy = new PhutilProxyException( pht( 'Error while updating the "%s" repository.', - $repository->getMonogram()), + $display_name), $ex); phlog($proxy); - return time() + $min_sleep; + $smart_wait = $repository->loadUpdateInterval($min_sleep); + return PhabricatorTime::getNow() + $smart_wait; } if (strlen($stderr)) { $stderr_msg = pht( 'Unexpected output while updating repository "%s": %s', - $monogram, + $display_name, $stderr); phlog($stderr_msg); } @@ -416,10 +461,10 @@ final class PhabricatorRepositoryPullLocalDaemon pht( 'Based on activity in repository "%s", considering a wait of %s '. 'seconds before update.', - $repository->getMonogram(), + $display_name, new PhutilNumber($smart_wait))); - return time() + $smart_wait; + return PhabricatorTime::getNow() + $smart_wait; } diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 3e59c7c53d..3ab3912f2c 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -1783,7 +1783,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO $smart_wait = $minimum; } - return $smart_wait; + return (int)$smart_wait; }