@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 execution order of Herald rules explicit

Summary: Fixes T6211. This gives Herald rules an explicit execution order, which seems generally good. See some discussion on T6211 and inline.

Test Plan:
- Added unit test.
- Dry ran rules and saw rules appear in the expected order in the transcript.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6211

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

+81
+2
src/__phutil_library_map__.php
··· 815 815 'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php', 816 816 'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php', 817 817 'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php', 818 + 'HeraldRuleTestCase' => 'applications/herald/storage/__tests__/HeraldRuleTestCase.php', 818 819 'HeraldRuleTransaction' => 'applications/herald/storage/HeraldRuleTransaction.php', 819 820 'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php', 820 821 'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php', ··· 3712 3713 'HeraldRulePHIDType' => 'PhabricatorPHIDType', 3713 3714 'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3714 3715 'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine', 3716 + 'HeraldRuleTestCase' => 'PhabricatorTestCase', 3715 3717 'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction', 3716 3718 'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment', 3717 3719 'HeraldRuleViewController' => 'HeraldController',
+2
src/applications/herald/engine/HeraldEngine.php
··· 49 49 assert_instances_of($rules, 'HeraldRule'); 50 50 $t_start = microtime(true); 51 51 52 + // Rules execute in a well-defined order: sort them into execution order. 53 + $rules = msort($rules, 'getRuleExecutionOrderSortKey'); 52 54 $rules = mpull($rules, null, 'getPHID'); 53 55 54 56 $this->transcript = new HeraldTranscript();
+36
src/applications/herald/storage/HeraldRule.php
··· 228 228 return $this->assertAttached($this->triggerObject); 229 229 } 230 230 231 + /** 232 + * Get a sortable key for rule execution order. 233 + * 234 + * Rules execute in a well-defined order: personal rules first, then object 235 + * rules, then global rules. Within each rule type, rules execute from lowest 236 + * ID to highest ID. 237 + * 238 + * This ordering allows more powerful rules (like global rules) to override 239 + * weaker rules (like personal rules) when multiple rules exist which try to 240 + * affect the same field. Executing from low IDs to high IDs makes 241 + * interactions easier to understand when adding new rules, because the newest 242 + * rules always happen last. 243 + * 244 + * @return string A sortable key for this rule. 245 + */ 246 + public function getRuleExecutionOrderSortKey() { 247 + 248 + $rule_type = $this->getRuleType(); 249 + 250 + switch ($rule_type) { 251 + case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 252 + $type_order = 1; 253 + break; 254 + case HeraldRuleTypeConfig::RULE_TYPE_OBJECT: 255 + $type_order = 2; 256 + break; 257 + case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 258 + $type_order = 3; 259 + break; 260 + default: 261 + throw new Exception(pht('Unknown rule type "%s"!', $rule_type)); 262 + } 263 + 264 + return sprintf('~%d%010d', $type_order, $this->getID()); 265 + } 266 + 231 267 232 268 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 233 269
+41
src/applications/herald/storage/__tests__/HeraldRuleTestCase.php
··· 1 + <?php 2 + 3 + final class HeraldRuleTestCase extends PhabricatorTestCase { 4 + 5 + public function testHeraldRuleExecutionOrder() { 6 + $rules = array( 7 + 1 => HeraldRuleTypeConfig::RULE_TYPE_GLOBAL, 8 + 2 => HeraldRuleTypeConfig::RULE_TYPE_GLOBAL, 9 + 3 => HeraldRuleTypeConfig::RULE_TYPE_OBJECT, 10 + 4 => HeraldRuleTypeConfig::RULE_TYPE_PERSONAL, 11 + 5 => HeraldRuleTypeConfig::RULE_TYPE_GLOBAL, 12 + 6 => HeraldRuleTypeConfig::RULE_TYPE_PERSONAL, 13 + ); 14 + 15 + foreach ($rules as $id => $type) { 16 + $rules[$id] = id(new HeraldRule()) 17 + ->setID($id) 18 + ->setRuleType($type); 19 + } 20 + 21 + shuffle($rules); 22 + $rules = msort($rules, 'getRuleExecutionOrderSortKey'); 23 + $this->assertEqual( 24 + array( 25 + // Personal 26 + 4, 27 + 6, 28 + 29 + // Object 30 + 3, 31 + 32 + // Global 33 + 1, 34 + 2, 35 + 5 36 + ), 37 + array_values(mpull($rules, 'getID'))); 38 + } 39 + 40 + 41 + }