@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.

Add bin/trigger, for testing event triggers

Summary:
Ref T6881. This makes it easier to fire a trigger and make sure it works properly. You can use the `--now` flag to travel through time, and test scheduling conditions with `--last` and `--next`. It will tell you when the trigger would reschedule.

Better than waiting 24 hours to see if things work.

Test Plan: Fired some backups, got useful output which made me think my code probably works correctly.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6881

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

+219
+1
bin/trigger
··· 1 + ../scripts/setup/manage_trigger.php
+21
scripts/setup/manage_trigger.php
··· 1 + #!/usr/bin/env php 2 + <?php 3 + 4 + $root = dirname(dirname(dirname(__FILE__))); 5 + require_once $root.'/scripts/__init_script__.php'; 6 + 7 + $args = new PhutilArgumentParser($argv); 8 + $args->setTagline('manage triggers'); 9 + $args->setSynopsis(<<<EOSYNOPSIS 10 + **trigger** __command__ [__options__] 11 + Manage event triggers. 12 + 13 + EOSYNOPSIS 14 + ); 15 + $args->parseStandardArguments(); 16 + 17 + $workflows = id(new PhutilSymbolLoader()) 18 + ->setAncestorClass('PhabricatorWorkerTriggerManagementWorkflow') 19 + ->loadObjects(); 20 + $workflows[] = new PhutilHelpArgumentWorkflow(); 21 + $args->parseWorkflows($workflows);
+4
src/__phutil_library_map__.php
··· 2603 2603 'PhabricatorWorkerTestCase' => 'infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php', 2604 2604 'PhabricatorWorkerTrigger' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTrigger.php', 2605 2605 'PhabricatorWorkerTriggerEvent' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTriggerEvent.php', 2606 + 'PhabricatorWorkerTriggerManagementFireWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementFireWorkflow.php', 2607 + 'PhabricatorWorkerTriggerManagementWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementWorkflow.php', 2606 2608 'PhabricatorWorkerTriggerPHIDType' => 'infrastructure/daemon/workers/phid/PhabricatorWorkerTriggerPHIDType.php', 2607 2609 'PhabricatorWorkerTriggerQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php', 2608 2610 'PhabricatorWorkerYieldException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerYieldException.php', ··· 5889 5891 'PhabricatorDestructibleInterface', 5890 5892 ), 5891 5893 'PhabricatorWorkerTriggerEvent' => 'PhabricatorWorkerDAO', 5894 + 'PhabricatorWorkerTriggerManagementFireWorkflow' => 'PhabricatorWorkerTriggerManagementWorkflow', 5895 + 'PhabricatorWorkerTriggerManagementWorkflow' => 'PhabricatorManagementWorkflow', 5892 5896 'PhabricatorWorkerTriggerPHIDType' => 'PhabricatorPHIDType', 5893 5897 'PhabricatorWorkerTriggerQuery' => 'PhabricatorOffsetPagedQuery', 5894 5898 'PhabricatorWorkerYieldException' => 'Exception',
+136
src/infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementFireWorkflow.php
··· 1 + <?php 2 + 3 + final class PhabricatorWorkerTriggerManagementFireWorkflow 4 + extends PhabricatorWorkerTriggerManagementWorkflow { 5 + 6 + protected function didConstruct() { 7 + $this 8 + ->setName('fire') 9 + ->setExamples('**fire** --id __id__') 10 + ->setSynopsis( 11 + pht( 12 + 'Activates selected triggers, firing them immediately.')) 13 + ->setArguments( 14 + array_merge( 15 + array( 16 + array( 17 + 'name' => 'now', 18 + 'param' => 'time', 19 + 'help' => pht( 20 + 'Fire the trigger as though the current time is a given '. 21 + 'time. This allows you to test how a trigger would behave '. 22 + 'if activated in the past or future. Defaults to the actual '. 23 + 'current time.'), 24 + ), 25 + array( 26 + 'name' => 'last', 27 + 'param' => 'time', 28 + 'help' => pht( 29 + 'Fire the trigger as though the last event occurred at a '. 30 + 'given time. Defaults to the actual last event time.'), 31 + ), 32 + array( 33 + 'name' => 'next', 34 + 'param' => 'time', 35 + 'help' => pht( 36 + 'Fire the trigger as though the next event was scheduled '. 37 + 'at a given time. Defaults to the actual time when the '. 38 + 'event is next scheduled to fire.'), 39 + ), 40 + ), 41 + $this->getTriggerSelectionArguments())); 42 + } 43 + 44 + public function execute(PhutilArgumentParser $args) { 45 + $console = PhutilConsole::getConsole(); 46 + $viewer = $this->getViewer(); 47 + $triggers = $this->loadTriggers($args); 48 + 49 + $now = $args->getArg('now'); 50 + $now = $this->parseTime($now); 51 + if (!$now) { 52 + $now = PhabricatorTime::getNow(); 53 + } 54 + 55 + PhabricatorTime::pushTime($now, date_default_timezone_get()); 56 + 57 + $console->writeOut( 58 + "%s\n", 59 + pht( 60 + 'Set current time to %s.', 61 + phabricator_datetime(PhabricatorTime::getNow(), $viewer))); 62 + 63 + $last_time = $this->parseTime($args->getArg('last')); 64 + $next_time = $this->parseTime($args->getArg('next')); 65 + 66 + PhabricatorWorker::setRunAllTasksInProcess(true); 67 + 68 + foreach ($triggers as $trigger) { 69 + $console->writeOut( 70 + "%s\n", 71 + pht('Executing trigger %s.', $this->describeTrigger($trigger))); 72 + 73 + $event = $trigger->getEvent(); 74 + if ($event) { 75 + if (!$last_time) { 76 + $last_time = $event->getLastEventEpoch(); 77 + } 78 + if (!$next_time) { 79 + $next_time = $event->getNextEventEpoch(); 80 + } 81 + } 82 + 83 + if (!$next_time) { 84 + $console->writeOut( 85 + "%s\n", 86 + pht( 87 + 'Trigger is not scheduled to execute. Use --at to simluate '. 88 + 'a scheduled event.')); 89 + continue; 90 + } else { 91 + $console->writeOut( 92 + "%s\n", 93 + pht( 94 + 'Executing event as though it was scheduled to execute at %s.', 95 + phabricator_datetime($next_time, $viewer))); 96 + } 97 + 98 + if (!$last_time) { 99 + $console->writeOut( 100 + "%s\n", 101 + pht( 102 + 'Executing event as though it never previously executed.')); 103 + } else { 104 + $console->writeOut( 105 + "%s\n", 106 + pht( 107 + 'Executing event as though it previously executed at %s.', 108 + phabricator_datetime($last_time, $viewer))); 109 + } 110 + 111 + $trigger->executeTrigger($last_time, $next_time); 112 + 113 + $reschedule_time = $trigger->getNextEventEpoch( 114 + $next_time, 115 + $is_reschedule = true); 116 + 117 + if (!$reschedule_time) { 118 + $console->writeOut( 119 + "%s\n", 120 + pht( 121 + 'After executing under these conditions, this event would never '. 122 + 'execute again.')); 123 + } else { 124 + $console->writeOut( 125 + "%s\n", 126 + pht( 127 + 'After executing under these conditions, this event would '. 128 + 'next execute at %s.', 129 + phabricator_datetime($reschedule_time, $viewer))); 130 + } 131 + } 132 + 133 + return 0; 134 + } 135 + 136 + }
+57
src/infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementWorkflow.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorWorkerTriggerManagementWorkflow 4 + extends PhabricatorManagementWorkflow { 5 + 6 + protected function getTriggerSelectionArguments() { 7 + return array( 8 + array( 9 + 'name' => 'id', 10 + 'param' => 'id', 11 + 'repeat' => true, 12 + 'help' => pht('Select one or more triggers by ID.'), 13 + ), 14 + ); 15 + } 16 + 17 + protected function loadTriggers(PhutilArgumentParser $args) { 18 + $ids = $args->getArg('id'); 19 + if (!$ids) { 20 + throw new PhutilArgumentUsageException( 21 + pht('Use --id to select triggers by ID.')); 22 + } 23 + 24 + $triggers = id(new PhabricatorWorkerTriggerQuery()) 25 + ->withIDs($ids) 26 + ->needEvents(true) 27 + ->execute(); 28 + $triggers = mpull($triggers, null, 'getID'); 29 + 30 + foreach ($ids as $id) { 31 + if (empty($triggers[$id])) { 32 + throw new PhutilArgumentUsageException( 33 + pht('No trigger exists with id "%s"!', $id)); 34 + } 35 + } 36 + 37 + return $triggers; 38 + } 39 + 40 + protected function describeTrigger(PhabricatorWorkerTrigger $trigger) { 41 + return pht('Trigger %d', $trigger->getID()); 42 + } 43 + 44 + protected function parseTime($time) { 45 + if (!strlen($time)) { 46 + return null; 47 + } 48 + 49 + $epoch = strtotime($time); 50 + if ($epoch <= 0) { 51 + throw new PhutilArgumentUsageException( 52 + pht('Unable to parse time "%s".', $time)); 53 + } 54 + return $epoch; 55 + } 56 + 57 + }