Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / nuance / worker / NuanceItemUpdateWorker.php
blobcd6637187c070935ef1053e9372845e3d82454dc
1 <?php
3 final class NuanceItemUpdateWorker
4 extends NuanceWorker {
6 protected function doWork() {
7 $item_phid = $this->getTaskDataValue('itemPHID');
9 $lock = $this->newLock($item_phid);
11 $lock->lock(1);
12 try {
13 $item = $this->loadItem($item_phid);
14 $this->updateItem($item);
15 $this->routeItem($item);
16 $this->applyCommands($item);
17 } catch (Exception $ex) {
18 $lock->unlock();
19 throw $ex;
22 $lock->unlock();
25 private function updateItem(NuanceItem $item) {
26 $impl = $item->getImplementation();
27 if (!$impl->canUpdateItems()) {
28 return null;
31 $viewer = $this->getViewer();
33 $impl->setViewer($viewer);
34 $impl->updateItem($item);
37 private function routeItem(NuanceItem $item) {
38 $status = $item->getStatus();
39 if ($status != NuanceItem::STATUS_ROUTING) {
40 return;
43 $source = $item->getSource();
45 // For now, always route items into the source's default queue.
47 $item
48 ->setQueuePHID($source->getDefaultQueuePHID())
49 ->setStatus(NuanceItem::STATUS_OPEN)
50 ->save();
53 private function applyCommands(NuanceItem $item) {
54 $viewer = $this->getViewer();
56 $commands = id(new NuanceItemCommandQuery())
57 ->setViewer($viewer)
58 ->withItemPHIDs(array($item->getPHID()))
59 ->withStatuses(
60 array(
61 NuanceItemCommand::STATUS_ISSUED,
63 ->execute();
64 $commands = msort($commands, 'getID');
66 $this->executeCommandList($item, $commands);
69 public function executeCommands(NuanceItem $item, array $commands) {
70 if (!$commands) {
71 return true;
74 $item_phid = $item->getPHID();
75 $viewer = $this->getViewer();
77 $lock = $this->newLock($item_phid);
78 try {
79 $lock->lock(1);
80 } catch (PhutilLockException $ex) {
81 return false;
84 try {
85 $item = $this->loadItem($item_phid);
87 // Reload commands now that we have a lock, to make sure we don't
88 // execute any commands twice by mistake.
89 $commands = id(new NuanceItemCommandQuery())
90 ->setViewer($viewer)
91 ->withIDs(mpull($commands, 'getID'))
92 ->execute();
94 $this->executeCommandList($item, $commands);
95 } catch (Exception $ex) {
96 $lock->unlock();
97 throw $ex;
100 $lock->unlock();
102 return true;
105 private function executeCommandList(NuanceItem $item, array $commands) {
106 $viewer = $this->getViewer();
108 $executors = NuanceCommandImplementation::getAllCommands();
109 foreach ($commands as $command) {
110 if ($command->getItemPHID() !== $item->getPHID()) {
111 throw new Exception(
112 pht('Trying to apply a command to the wrong item!'));
115 if ($command->getStatus() !== NuanceItemCommand::STATUS_ISSUED) {
116 // Never execute commands which have already been issued.
117 continue;
120 $command
121 ->setStatus(NuanceItemCommand::STATUS_EXECUTING)
122 ->save();
124 try {
125 $command_key = $command->getCommand();
127 $executor = idx($executors, $command_key);
128 if (!$executor) {
129 throw new Exception(
130 pht(
131 'Unable to execute command "%s": this command does not have '.
132 'a recognized command implementation.',
133 $command_key));
136 $executor = clone $executor;
138 $executor
139 ->setActor($viewer)
140 ->applyCommand($item, $command);
142 $command
143 ->setStatus(NuanceItemCommand::STATUS_DONE)
144 ->save();
145 } catch (Exception $ex) {
146 $command
147 ->setStatus(NuanceItemCommand::STATUS_FAILED)
148 ->save();
150 throw $ex;
155 private function newLock($item_phid) {
156 $hash = PhabricatorHash::digestForIndex($item_phid);
157 $lock_key = "nuance.item.{$hash}";
158 return PhabricatorGlobalLock::newLock($lock_key);