Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/search/index/PhabricatorSearchDocumentIndexer.php b/src/applications/search/index/PhabricatorSearchDocumentIndexer.php
index 5e2140d4e0..a9ecc3e9c0 100644
--- a/src/applications/search/index/PhabricatorSearchDocumentIndexer.php
+++ b/src/applications/search/index/PhabricatorSearchDocumentIndexer.php
@@ -1,199 +1,181 @@
<?php
abstract class PhabricatorSearchDocumentIndexer extends Phobject {
private $context;
protected function setContext($context) {
$this->context = $context;
return $this;
}
protected function getContext() {
return $this->context;
}
abstract public function getIndexableObject();
abstract protected function buildAbstractDocumentByPHID($phid);
protected function getViewer() {
return PhabricatorUser::getOmnipotentUser();
}
public function shouldIndexDocumentByPHID($phid) {
$object = $this->getIndexableObject();
return (phid_get_type($phid) == phid_get_type($object->generatePHID()));
}
public function getIndexIterator() {
$object = $this->getIndexableObject();
return new LiskMigrationIterator($object);
}
protected function loadDocumentByPHID($phid) {
$object = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs(array($phid))
->executeOne();
if (!$object) {
throw new Exception(pht("Unable to load object by PHID '%s'!", $phid));
}
return $object;
}
public function indexDocumentByPHID($phid, $context) {
- try {
- $this->setContext($context);
+ $this->setContext($context);
- $document = $this->buildAbstractDocumentByPHID($phid);
- if ($document === null) {
- // This indexer doesn't build a document index, so we're done.
- return $this;
- }
+ $document = $this->buildAbstractDocumentByPHID($phid);
+ if ($document === null) {
+ // This indexer doesn't build a document index, so we're done.
+ return $this;
+ }
- $object = $this->loadDocumentByPHID($phid);
+ $object = $this->loadDocumentByPHID($phid);
- // Automatically rebuild CustomField indexes if the object uses custom
- // fields.
- if ($object instanceof PhabricatorCustomFieldInterface) {
- $this->indexCustomFields($document, $object);
- }
+ // Automatically rebuild CustomField indexes if the object uses custom
+ // fields.
+ if ($object instanceof PhabricatorCustomFieldInterface) {
+ $this->indexCustomFields($document, $object);
+ }
- // Automatically rebuild subscriber indexes if the object is subscribable.
- if ($object instanceof PhabricatorSubscribableInterface) {
- $this->indexSubscribers($document);
- }
+ // Automatically rebuild subscriber indexes if the object is subscribable.
+ if ($object instanceof PhabricatorSubscribableInterface) {
+ $this->indexSubscribers($document);
+ }
- // Automatically build project relationships
- if ($object instanceof PhabricatorProjectInterface) {
- $this->indexProjects($document, $object);
- }
+ // Automatically build project relationships
+ if ($object instanceof PhabricatorProjectInterface) {
+ $this->indexProjects($document, $object);
+ }
- $engine = PhabricatorSearchEngine::loadEngine();
- try {
- $engine->reindexAbstractDocument($document);
- } catch (Exception $ex) {
- phlog(
- pht(
- 'Unable to index document %s with engine %s.',
- $document->getPHID(),
- get_class($engine)));
- phlog($ex);
- }
+ $engine = PhabricatorSearchEngine::loadEngine();
+ $engine->reindexAbstractDocument($document);
- $this->dispatchDidUpdateIndexEvent($phid, $document);
- } catch (Exception $ex) {
- phlog(
- pht(
- 'Unable to build document %s with indexer %s.',
- $phid,
- get_class($this)));
- phlog($ex);
- }
+ $this->dispatchDidUpdateIndexEvent($phid, $document);
return $this;
}
protected function newDocument($phid) {
return id(new PhabricatorSearchAbstractDocument())
->setPHID($phid)
->setDocumentType(phid_get_type($phid));
}
protected function indexSubscribers(
PhabricatorSearchAbstractDocument $doc) {
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
$doc->getPHID());
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($subscribers)
->execute();
foreach ($handles as $phid => $handle) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
$phid,
$handle->getType(),
$doc->getDocumentModified()); // Bogus timestamp.
}
}
protected function indexProjects(
PhabricatorSearchAbstractDocument $doc,
PhabricatorProjectInterface $object) {
$project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$object->getPHID(),
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
if ($project_phids) {
foreach ($project_phids as $project_phid) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_PROJECT,
$project_phid,
PhabricatorProjectProjectPHIDType::TYPECONST,
$doc->getDocumentModified()); // Bogus timestamp.
}
}
}
protected function indexTransactions(
PhabricatorSearchAbstractDocument $doc,
PhabricatorApplicationTransactionQuery $query,
array $phids) {
$xactions = id(clone $query)
->setViewer($this->getViewer())
->withObjectPHIDs($phids)
->execute();
foreach ($xactions as $xaction) {
if (!$xaction->hasComment()) {
continue;
}
$comment = $xaction->getComment();
$doc->addField(
PhabricatorSearchDocumentFieldType::FIELD_COMMENT,
$comment->getContent());
}
}
protected function indexCustomFields(
PhabricatorSearchAbstractDocument $document,
PhabricatorCustomFieldInterface $object) {
// Rebuild the ApplicationSearch indexes. These are internal and not part of
// the fulltext search, but putting them in this workflow allows users to
// use the same tools to rebuild the indexes, which is easy to understand.
$field_list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_DEFAULT);
$field_list->setViewer($this->getViewer());
$field_list->readFieldsFromStorage($object);
// Rebuild ApplicationSearch indexes.
$field_list->rebuildIndexes($object);
// Rebuild global search indexes.
$field_list->updateAbstractDocument($document);
}
private function dispatchDidUpdateIndexEvent(
$phid,
PhabricatorSearchAbstractDocument $document) {
$event = new PhabricatorEvent(
PhabricatorEventType::TYPE_SEARCH_DIDUPDATEINDEX,
array(
'phid' => $phid,
'object' => $this->loadDocumentByPHID($phid),
'document' => $document,
));
$event->setUser($this->getViewer());
PhutilEventEngine::dispatchEvent($event);
}
}
diff --git a/src/applications/search/management/PhabricatorSearchManagementIndexWorkflow.php b/src/applications/search/management/PhabricatorSearchManagementIndexWorkflow.php
index 853f8c42c1..b1afc3619b 100644
--- a/src/applications/search/management/PhabricatorSearchManagementIndexWorkflow.php
+++ b/src/applications/search/management/PhabricatorSearchManagementIndexWorkflow.php
@@ -1,147 +1,160 @@
<?php
final class PhabricatorSearchManagementIndexWorkflow
extends PhabricatorSearchManagementWorkflow {
protected function didConstruct() {
$this
->setName('index')
->setSynopsis(pht('Build or rebuild search indexes.'))
->setExamples(
"**index** D123\n".
"**index** --type DREV\n".
"**index** --all")
->setArguments(
array(
array(
'name' => 'all',
'help' => pht('Reindex all documents.'),
),
array(
'name' => 'type',
'param' => 'TYPE',
'help' => pht('PHID type to reindex, like "TASK" or "DREV".'),
),
array(
'name' => 'background',
'help' => pht(
'Instead of indexing in this process, queue tasks for '.
'the daemons. This can improve performance, but makes '.
'it more difficult to debug search indexing.'),
),
array(
'name' => 'objects',
'wildcard' => true,
),
));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$is_all = $args->getArg('all');
$is_type = $args->getArg('type');
$obj_names = $args->getArg('objects');
if ($obj_names && ($is_all || $is_type)) {
throw new PhutilArgumentUsageException(
pht(
"You can not name objects to index alongside the '%s' or '%s' flags.",
'--all',
'--type'));
} else if (!$obj_names && !($is_all || $is_type)) {
throw new PhutilArgumentUsageException(
pht(
"Provide one of '%s', '%s' or a list of object names.",
'--all',
'--type'));
}
if ($obj_names) {
$phids = $this->loadPHIDsByNames($obj_names);
} else {
$phids = $this->loadPHIDsByTypes($is_type);
}
if (!$phids) {
throw new PhutilArgumentUsageException(pht('Nothing to index!'));
}
if ($args->getArg('background')) {
$is_background = true;
} else {
PhabricatorWorker::setRunAllTasksInProcess(true);
$is_background = false;
}
if (!$is_background) {
$console->writeOut(
"%s\n",
pht(
'Run this workflow with "%s" to queue tasks for the daemon workers.',
'--background'));
}
$groups = phid_group_by_type($phids);
foreach ($groups as $group_type => $group) {
$console->writeOut(
"%s\n",
pht('Indexing %d object(s) of type %s.', count($group), $group_type));
}
$bar = id(new PhutilConsoleProgressBar())
->setTotal(count($phids));
+ $any_success = false;
$indexer = new PhabricatorSearchIndexer();
foreach ($phids as $phid) {
- $indexer->queueDocumentForIndexing($phid);
+ try {
+ $indexer->queueDocumentForIndexing($phid);
+ $any_success = true;
+ } catch (Exception $ex) {
+ phlog($ex);
+ }
+
$bar->update(1);
}
$bar->done();
+
+ if (!$any_success) {
+ throw new Exception(
+ pht('Failed to rebuild search index for any documents.'));
+ }
+
}
private function loadPHIDsByNames(array $names) {
$query = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withNames($names);
$query->execute();
$objects = $query->getNamedResults();
foreach ($names as $name) {
if (empty($objects[$name])) {
throw new PhutilArgumentUsageException(
pht(
"'%s' is not the name of a known object.",
$name));
}
}
return mpull($objects, 'getPHID');
}
private function loadPHIDsByTypes($type) {
$indexers = id(new PhutilClassMapQuery())
->setAncestorClass('PhabricatorSearchDocumentIndexer')
->execute();
$phids = array();
foreach ($indexers as $indexer) {
$indexer_phid = $indexer->getIndexableObject()->generatePHID();
$indexer_type = phid_get_type($indexer_phid);
if ($type && strcasecmp($indexer_type, $type)) {
continue;
}
$iterator = $indexer->getIndexIterator();
foreach ($iterator as $object) {
$phids[] = $object->getPHID();
}
}
return $phids;
}
}
diff --git a/src/applications/search/worker/PhabricatorSearchWorker.php b/src/applications/search/worker/PhabricatorSearchWorker.php
index 873d9ff2dc..689602ab06 100644
--- a/src/applications/search/worker/PhabricatorSearchWorker.php
+++ b/src/applications/search/worker/PhabricatorSearchWorker.php
@@ -1,15 +1,23 @@
<?php
final class PhabricatorSearchWorker extends PhabricatorWorker {
protected function doWork() {
$data = $this->getTaskData();
$phid = idx($data, 'documentPHID');
$context = idx($data, 'context');
- id(new PhabricatorSearchIndexer())
- ->indexDocumentByPHID($phid, $context);
+ try {
+ id(new PhabricatorSearchIndexer())
+ ->indexDocumentByPHID($phid, $context);
+ } catch (Exception $ex) {
+ throw new PhabricatorWorkerPermanentFailureException(
+ pht(
+ 'Failed to update search index for document "%s": %s',
+ $phid,
+ $ex->getMessage()));
+ }
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Apr 30, 4:17 AM (1 d, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
108548
Default Alt Text
(12 KB)

Event Timeline