From 6a3824a61d44551e3bbe7d28ce735d96e9eb96ac Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 17 Feb 2015 15:23:24 -0800 Subject: [PATCH] Fix an issue where PullLocal daemon could spin in an error loop Summary: Fixes T7106. If you have bad credentials AND you've pushed an "update this repository" message into the queue, the loop above this level ends up resetting the timer every time we go through it, so the daemon spins in a loop failing forever. Test Plan: - Created a repo with bad credentials. - Clicekd "updated now" to queue an update message. - Saw daemon run in a loop. - Applied patch, no loop. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7106 Differential Revision: https://secure.phabricator.com/D11795 --- .../PhabricatorRepositoryPullLocalDaemon.php | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php index 9f07ce491b..b59c4b859a 100644 --- a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php +++ b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php @@ -27,6 +27,7 @@ final class PhabricatorRepositoryPullLocalDaemon extends PhabricatorDaemon { + private $statusMessageCursor = 0; /* -( Pulling Repositories )----------------------------------------------- */ @@ -259,8 +260,25 @@ final class PhabricatorRepositoryPullLocalDaemon */ private function loadRepositoryUpdateMessages() { $type_need_update = PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE; - return id(new PhabricatorRepositoryStatusMessage()) - ->loadAllWhere('statusType = %s', $type_need_update); + $messages = id(new PhabricatorRepositoryStatusMessage())->loadAllWhere( + 'statusType = %s AND id > %d', + $type_need_update, + $this->statusMessageCursor); + + // Keep track of messages we've seen so that we don't load them again. + // If we reload messages, we can get stuck a loop if we have a failing + // repository: we update immediately in response to the message, but do + // not clear the message because the update does not succeed. We then + // immediately retry. Instead, messages are only permitted to trigger + // an immediate update once. + + foreach ($messages as $message) { + $this->statusMessageCursor = max( + $this->statusMessageCursor, + $message->getID()); + } + + return $messages; }