From 041040c42226f2362a702c69c38cd3d3115e59e2 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Fri, 2 Nov 2012 13:34:18 -0700 Subject: [PATCH] post feed stories to arbitrary uris via a new Worker Summary: so folks can write applications and whatnot. Test Plan: set feed.http-hooks to local dev instance (200) and localhost (500) in my conf. Verified succcess and retrying respectively. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T305 Differential Revision: https://secure.phabricator.com/D3874 --- conf/default.conf.php | 9 ++++ src/__phutil_library_map__.php | 2 + .../feed/PhabricatorFeedStoryPublisher.php | 10 +++- .../feed/worker/FeedPublisherWorker.php | 54 +++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/applications/feed/worker/FeedPublisherWorker.php diff --git a/conf/default.conf.php b/conf/default.conf.php index 725bb0bbdd..0bf46fe894 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -1140,6 +1140,15 @@ return array( // to work properly. 'feed.public' => false, + // If you set this to a list of http URIs, when a feed story is published a + // task will be created for each uri that posts the story data to the uri. + // Daemons automagically retry failures 100 times, waiting $fail_count * 60s + // between each subsequent failure. Be sure to keep the daemon console + // (/daemon/) open while developing and testing your end points. + // + // NOTE: URIs are not validated, the URI must return http status 200 within + // 30 seconds, and no permission checks are performed. + 'feed.http-hooks' => array(), // -- Drydock --------------------------------------------------------------- // diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index d2e9c42053..73688f1c07 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -440,6 +440,7 @@ phutil_register_library_map(array( 'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php', 'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php', 'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php', + 'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php', 'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php', 'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php', 'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php', @@ -1672,6 +1673,7 @@ phutil_register_library_map(array( 'DrydockResourceStatus' => 'DrydockConstants', 'DrydockSSHCommandInterface' => 'DrydockCommandInterface', 'DrydockWebrootInterface' => 'DrydockInterface', + 'FeedPublisherWorker' => 'PhabricatorWorker', 'HarbormasterDAO' => 'PhabricatorLiskDAO', 'HarbormasterObject' => 'HarbormasterDAO', 'HarbormasterScratchTable' => 'HarbormasterDAO', diff --git a/src/applications/feed/PhabricatorFeedStoryPublisher.php b/src/applications/feed/PhabricatorFeedStoryPublisher.php index 19458d41a0..b3172d6d47 100644 --- a/src/applications/feed/PhabricatorFeedStoryPublisher.php +++ b/src/applications/feed/PhabricatorFeedStoryPublisher.php @@ -119,10 +119,18 @@ final class PhabricatorFeedStoryPublisher { $this->insertNotifications($chrono_key); $this->sendNotification($chrono_key); } + + $uris = PhabricatorEnv::getEnvConfig('feed.http-hooks', array()); + foreach ($uris as $uri) { + $task = PhabricatorWorker::scheduleTask( + 'FeedPublisherWorker', + array('chrono_key' => $chrono_key, 'uri' => $uri) + ); + } + return $story; } - private function insertNotifications($chrono_key) { $subscribed_phids = $this->subscribedPHIDs; $subscribed_phids = array_diff( diff --git a/src/applications/feed/worker/FeedPublisherWorker.php b/src/applications/feed/worker/FeedPublisherWorker.php new file mode 100644 index 0000000000..e33dfd68dc --- /dev/null +++ b/src/applications/feed/worker/FeedPublisherWorker.php @@ -0,0 +1,54 @@ +getTaskData(); + $chrono_key = $task_data['chrono_key']; + $uri = $task_data['uri']; + + $story = id(new PhabricatorFeedStoryData()) + ->loadOneWhere('chronologicalKey = %s', $chrono_key); + + if (!$story) { + throw new PhabricatorWorkerPermanentFailureException( + 'Feed story was deleted.' + ); + } + + $data = array( + 'storyID' => $story->getID(), + 'storyType' => $story->getStoryType(), + 'storyData' => $story->getStoryData(), + 'storyAuthorPHID' => $story->getAuthorPHID(), + 'epoch' => $story->getEpoch(), + ); + + id(new HTTPFuture($uri, $data)) + ->setMethod('POST') + ->setTimeout(30) + ->resolvex(); + + } + + public function getWaitBeforeRetry(PhabricatorWorkerTask $task) { + return max($task->getFailureCount(), 1) * 60; + } + +}