@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make repository daemons periodically check for out-of-sync repositories

Summary:
See PHI1015. If you add new repository nodes to a cluster, we may not actually sync some repositories for up to 6 hours (if they've had no commits for 30 days).

Add an explicit check for out-of-sync repositories to trigger background sync.

Test Plan:
- Ran `bin/phd debug pullocal`.
- Fiddled with the `repository_workingcopy` version table to put the local node in and out of sync with the cluster.
- Saw appropriate responses in the daemon (sync; wait if the last sync trigger was too recent).

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20078

+72 -1
+71
src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
··· 73 73 $futures = array(); 74 74 $queue = array(); 75 75 76 + $sync_wait = phutil_units('2 minutes in seconds'); 77 + $last_sync = array(); 78 + 76 79 while (!$this->shouldExit()) { 77 80 PhabricatorCaches::destroyRequestCache(); 78 81 $device = AlmanacKeys::getLiveDevice(); ··· 94 97 $repo->getMonogram())); 95 98 96 99 $retry_after[$message->getRepositoryID()] = time(); 100 + } 101 + 102 + if ($device) { 103 + $unsynchronized = $this->loadUnsynchronizedRepositories($device); 104 + $now = PhabricatorTime::getNow(); 105 + foreach ($unsynchronized as $repository) { 106 + $id = $repository->getID(); 107 + 108 + $this->log( 109 + pht( 110 + 'Cluster repository ("%s") is out of sync on this node ("%s").', 111 + $repository->getDisplayName(), 112 + $device->getName())); 113 + 114 + // Don't let out-of-sync conditions trigger updates too frequently, 115 + // since we don't want to get trapped in a death spiral if sync is 116 + // failing. 117 + $sync_at = idx($last_sync, $id, 0); 118 + $wait_duration = ($now - $sync_at); 119 + if ($wait_duration < $sync_wait) { 120 + $this->log( 121 + pht( 122 + 'Skipping forced out-of-sync update because the last update '. 123 + 'was too recent (%s seconds ago).', 124 + $wait_duration)); 125 + continue; 126 + } 127 + 128 + $last_sync[$id] = $now; 129 + $retry_after[$id] = $now; 130 + } 97 131 } 98 132 99 133 // If any repositories were deleted, remove them from the retry timer map ··· 519 553 } 520 554 521 555 return false; 556 + } 557 + 558 + private function loadUnsynchronizedRepositories(AlmanacDevice $device) { 559 + $viewer = $this->getViewer(); 560 + $table = new PhabricatorRepositoryWorkingCopyVersion(); 561 + $conn = $table->establishConnection('r'); 562 + 563 + $our_versions = queryfx_all( 564 + $conn, 565 + 'SELECT repositoryPHID, repositoryVersion FROM %R WHERE devicePHID = %s', 566 + $table, 567 + $device->getPHID()); 568 + $our_versions = ipull($our_versions, 'repositoryVersion', 'repositoryPHID'); 569 + 570 + $max_versions = queryfx_all( 571 + $conn, 572 + 'SELECT repositoryPHID, MAX(repositoryVersion) maxVersion FROM %R 573 + GROUP BY repositoryPHID', 574 + $table); 575 + $max_versions = ipull($max_versions, 'maxVersion', 'repositoryPHID'); 576 + 577 + $unsynchronized_phids = array(); 578 + foreach ($max_versions as $repository_phid => $max_version) { 579 + $our_version = idx($our_versions, $repository_phid); 580 + if (($our_version === null) || ($our_version < $max_version)) { 581 + $unsynchronized_phids[] = $repository_phid; 582 + } 583 + } 584 + 585 + if (!$unsynchronized_phids) { 586 + return array(); 587 + } 588 + 589 + return id(new PhabricatorRepositoryQuery()) 590 + ->setViewer($viewer) 591 + ->withPHIDs($unsynchronized_phids) 592 + ->execute(); 522 593 } 523 594 524 595 }
+1 -1
src/applications/repository/management/PhabricatorRepositoryManagementWorkflow.php
··· 7 7 $identifiers = $args->getArg($param); 8 8 9 9 if (!$identifiers) { 10 - return null; 10 + return array(); 11 11 } 12 12 13 13 $query = id(new PhabricatorRepositoryQuery())