From da50aef7f218118b49856431630a885c94989a0e Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 12 Sep 2013 13:05:54 -0700 Subject: [PATCH] Add event dispatch for updated search indexes Summary: See discussion in D6955. Provide an event for applications and users to update secondary search indexes. Facebook: I don't recall exactly how all the search stuff is rigged up, but this might provide a more practical / less fragile alternative. I think it publishes into ElasticSearch now, and then intern somehow handles the result merge at display time, implictly relying on Phabricator's storage format? A cleaner approach might be to publish a secondary "intern" index in a standard format. Test Plan: Ran `bin/search index --type proj --trace`, saw events fire. Reviewers: btrahan Reviewed By: btrahan CC: FacebookPOC, aran Differential Revision: https://secure.phabricator.com/D6956 --- .../PhabricatorSearchDocumentIndexer.php | 20 +++++++++-- src/docs/user/userguide/events.diviner | 35 +++++++++++++++++++ .../events/constant/PhabricatorEventType.php | 2 ++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/applications/search/index/PhabricatorSearchDocumentIndexer.php b/src/applications/search/index/PhabricatorSearchDocumentIndexer.php index b7fddf568c..5bb88c9bdb 100644 --- a/src/applications/search/index/PhabricatorSearchDocumentIndexer.php +++ b/src/applications/search/index/PhabricatorSearchDocumentIndexer.php @@ -44,13 +44,14 @@ abstract class PhabricatorSearchDocumentIndexer { $phid = $document->getPHID(); $class = get_class($engine); - phlog("Unable to index document {$phid} by engine {$class}."); + phlog("Unable to index document {$phid} with engine {$class}."); phlog($ex); } + $this->dispatchDidUpdateIndexEvent($phid, $document); } catch (Exception $ex) { $class = get_class($this); - phlog("Unable to build document {$phid} by indexer {$class}."); + phlog("Unable to build document {$phid} with indexer {$class}."); phlog($ex); } @@ -105,4 +106,19 @@ abstract class PhabricatorSearchDocumentIndexer { } } + 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/docs/user/userguide/events.diviner b/src/docs/user/userguide/events.diviner index 07f0f39b63..b70b0fad42 100644 --- a/src/docs/user/userguide/events.diviner +++ b/src/docs/user/userguide/events.diviner @@ -308,6 +308,41 @@ edit, but before it commits the transactions. Data available on this event: This is similar to the previous event (will edit edges) but occurs after the edit completes. +== Search: Did Update Index == + +The constant for this event is +`PhabricatorEventType::TYPE_SEARCH_DIDUPDATEINDEX`. + +This event is dispatched from the Search application's indexing engine, after +it indexes a document. It allows you to publish search-like indexes into other +systems. + +Note that this event happens after the update is fully complete: you can not +prevent or modify the update. Further, the event may fire significantly later +in real time than the update, as indexing may occur in the background. You +should use other events if you need guarantees about when the event executes. + +Finally, this event may fire more than once for a single update. For example, +if the search indexes are rebuilt, this event will fire on objects which have +not actually changed. + +So, good use cases for event listeners are: + + - Updating secondary search indexes. + +Bad use cases are: + + - Editing the object or document. + - Anything with side effects, like sending email. + +Data available on this event: + + - `phid` The PHID of the updated object. + - `object` The object which was updated (like a @{class:ManiphesTask}). + - `document` The @{class:PhabricatorSearchAbstractDocument} which was indexed. + This contains an abstract representation of the object, and may be useful + in populating secondary indexes because it provides a uniform API. + == Test: Did Run Test == The constant for this event is diff --git a/src/infrastructure/events/constant/PhabricatorEventType.php b/src/infrastructure/events/constant/PhabricatorEventType.php index aec70db8d2..49ff1fdef2 100644 --- a/src/infrastructure/events/constant/PhabricatorEventType.php +++ b/src/infrastructure/events/constant/PhabricatorEventType.php @@ -39,4 +39,6 @@ final class PhabricatorEventType extends PhutilEventType { const TYPE_AUTH_WILLREGISTERUSER = 'auth.willRegisterUser'; const TYPE_AUTH_WILLLOGINUSER = 'auth.willLoginUser'; + const TYPE_SEARCH_DIDUPDATEINDEX = 'search.didUpdateIndex'; + }