mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-24 14:30:56 +01:00
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
This commit is contained in:
parent
3c6781b177
commit
5f82805068
4 changed files with 81 additions and 0 deletions
|
@ -815,6 +815,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php',
|
'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php',
|
||||||
'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
|
'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
|
||||||
'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php',
|
'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php',
|
||||||
|
'HeraldRuleTestCase' => 'applications/herald/storage/__tests__/HeraldRuleTestCase.php',
|
||||||
'HeraldRuleTransaction' => 'applications/herald/storage/HeraldRuleTransaction.php',
|
'HeraldRuleTransaction' => 'applications/herald/storage/HeraldRuleTransaction.php',
|
||||||
'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php',
|
'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php',
|
||||||
'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php',
|
'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php',
|
||||||
|
@ -3712,6 +3713,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldRulePHIDType' => 'PhabricatorPHIDType',
|
'HeraldRulePHIDType' => 'PhabricatorPHIDType',
|
||||||
'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
|
'HeraldRuleTestCase' => 'PhabricatorTestCase',
|
||||||
'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction',
|
'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||||
'HeraldRuleViewController' => 'HeraldController',
|
'HeraldRuleViewController' => 'HeraldController',
|
||||||
|
|
|
@ -49,6 +49,8 @@ final class HeraldEngine {
|
||||||
assert_instances_of($rules, 'HeraldRule');
|
assert_instances_of($rules, 'HeraldRule');
|
||||||
$t_start = microtime(true);
|
$t_start = microtime(true);
|
||||||
|
|
||||||
|
// Rules execute in a well-defined order: sort them into execution order.
|
||||||
|
$rules = msort($rules, 'getRuleExecutionOrderSortKey');
|
||||||
$rules = mpull($rules, null, 'getPHID');
|
$rules = mpull($rules, null, 'getPHID');
|
||||||
|
|
||||||
$this->transcript = new HeraldTranscript();
|
$this->transcript = new HeraldTranscript();
|
||||||
|
|
|
@ -228,6 +228,42 @@ final class HeraldRule extends HeraldDAO
|
||||||
return $this->assertAttached($this->triggerObject);
|
return $this->assertAttached($this->triggerObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a sortable key for rule execution order.
|
||||||
|
*
|
||||||
|
* Rules execute in a well-defined order: personal rules first, then object
|
||||||
|
* rules, then global rules. Within each rule type, rules execute from lowest
|
||||||
|
* ID to highest ID.
|
||||||
|
*
|
||||||
|
* This ordering allows more powerful rules (like global rules) to override
|
||||||
|
* weaker rules (like personal rules) when multiple rules exist which try to
|
||||||
|
* affect the same field. Executing from low IDs to high IDs makes
|
||||||
|
* interactions easier to understand when adding new rules, because the newest
|
||||||
|
* rules always happen last.
|
||||||
|
*
|
||||||
|
* @return string A sortable key for this rule.
|
||||||
|
*/
|
||||||
|
public function getRuleExecutionOrderSortKey() {
|
||||||
|
|
||||||
|
$rule_type = $this->getRuleType();
|
||||||
|
|
||||||
|
switch ($rule_type) {
|
||||||
|
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
|
||||||
|
$type_order = 1;
|
||||||
|
break;
|
||||||
|
case HeraldRuleTypeConfig::RULE_TYPE_OBJECT:
|
||||||
|
$type_order = 2;
|
||||||
|
break;
|
||||||
|
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
|
||||||
|
$type_order = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception(pht('Unknown rule type "%s"!', $rule_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('~%d%010d', $type_order, $this->getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HeraldRuleTestCase extends PhabricatorTestCase {
|
||||||
|
|
||||||
|
public function testHeraldRuleExecutionOrder() {
|
||||||
|
$rules = array(
|
||||||
|
1 => HeraldRuleTypeConfig::RULE_TYPE_GLOBAL,
|
||||||
|
2 => HeraldRuleTypeConfig::RULE_TYPE_GLOBAL,
|
||||||
|
3 => HeraldRuleTypeConfig::RULE_TYPE_OBJECT,
|
||||||
|
4 => HeraldRuleTypeConfig::RULE_TYPE_PERSONAL,
|
||||||
|
5 => HeraldRuleTypeConfig::RULE_TYPE_GLOBAL,
|
||||||
|
6 => HeraldRuleTypeConfig::RULE_TYPE_PERSONAL,
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rules as $id => $type) {
|
||||||
|
$rules[$id] = id(new HeraldRule())
|
||||||
|
->setID($id)
|
||||||
|
->setRuleType($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffle($rules);
|
||||||
|
$rules = msort($rules, 'getRuleExecutionOrderSortKey');
|
||||||
|
$this->assertEqual(
|
||||||
|
array(
|
||||||
|
// Personal
|
||||||
|
4,
|
||||||
|
6,
|
||||||
|
|
||||||
|
// Object
|
||||||
|
3,
|
||||||
|
|
||||||
|
// Global
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
5
|
||||||
|
),
|
||||||
|
array_values(mpull($rules, 'getID')));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue