repository = $repository; return $this; } /** * @task config */ protected function getRepository() { if ($this->repository === null) { throw new PhutilInvalidStateException('setRepository'); } return $this->repository; } /** * @task config */ public function setVerbose($verbose) { $this->verbose = $verbose; return $this; } /** * @task config */ public function getVerbose() { return $this->verbose; } public function getViewer() { return PhabricatorUser::getOmnipotentUser(); } protected function newRepositoryLock( PhabricatorRepository $repository, $lock_key, $lock_device_only) { $lock_parts = array( 'repositoryPHID' => $repository->getPHID(), ); if ($lock_device_only) { $device = AlmanacKeys::getLiveDevice(); if ($device) { $lock_parts['devicePHID'] = $device->getPHID(); } } return PhabricatorGlobalLock::newLock($lock_key, $lock_parts); } /** * @task internal */ protected function log($pattern /* ... */) { if ($this->getVerbose()) { $console = PhutilConsole::getConsole(); $argv = func_get_args(); array_unshift($argv, "%s\n"); call_user_func_array(array($console, 'writeOut'), $argv); } return $this; } final protected function queueCommitImportTask( PhabricatorRepository $repository, $commit_phid, $task_priority, $via) { $vcs = $repository->getVersionControlSystem(); switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $class = 'PhabricatorRepositoryGitCommitMessageParserWorker'; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $class = 'PhabricatorRepositorySvnCommitMessageParserWorker'; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $class = 'PhabricatorRepositoryMercurialCommitMessageParserWorker'; break; default: throw new Exception( pht( 'Unknown repository type "%s"!', $vcs)); } $data = array( 'commitPHID' => $commit_phid, ); if ($via !== null) { $data['via'] = $via; } $options = array( 'priority' => $task_priority, 'objectPHID' => $commit_phid, 'containerPHID' => $repository->getPHID(), ); PhabricatorWorker::scheduleTask($class, $data, $options); } /** * @param PhabricatorRepository $repository * @param array $refs */ final protected function getImportTaskPriority( PhabricatorRepository $repository, array $refs) { assert_instances_of($refs, PhabricatorRepositoryCommitRef::class); // If the repository is importing for the first time, we schedule tasks // at IMPORT priority, which is very low. Making progress on importing a // new repository for the first time is less important than any other // daemon task. // If the repository has finished importing and we're just catching up // on recent commits, we usually schedule discovery at COMMIT priority, // which is slightly below the default priority. // Note that followup tasks and triggered tasks (like those generated by // Herald or Harbormaster) will queue at DEFAULT priority, so that each // commit tends to fully import before we start the next one. This tends // to give imports fairly predictable progress. See T11677 for some // discussion. if ($repository->isImporting()) { $this->log( pht( 'Importing %s commit(s) at low priority ("PRIORITY_IMPORT") '. 'because this repository is still importing.', phutil_count($refs))); return PhabricatorWorker::PRIORITY_IMPORT; } // See T13369. If we've discovered a lot of commits at once, import them // at lower priority. // This is mostly aimed at reducing the impact that synchronizing thousands // of commits from a remote upstream has on other repositories. The queue // is "mostly FIFO", so queueing a thousand commit imports can stall other // repositories. // In a perfect world we'd probably give repositories round-robin queue // priority, but we don't currently have the primitives for this and there // isn't a strong case for building them. // Use "a whole lot of commits showed up at once" as a heuristic for // detecting "someone synchronized an upstream", and import them at a lower // priority to more closely approximate fair scheduling. if (count($refs) >= PhabricatorRepository::LOWPRI_THRESHOLD) { $this->log( pht( 'Importing %s commits at low priority ("PRIORITY_IMPORT") '. 'because many commits were discovered at once.', phutil_count($refs))); return PhabricatorWorker::PRIORITY_IMPORT; } // Otherwise, import at normal priority. if ($refs) { $this->log( pht( 'Importing %s commit(s) at normal priority ("PRIORITY_COMMIT").', phutil_count($refs))); } return PhabricatorWorker::PRIORITY_COMMIT; } }