Path: blob/master/src/applications/nuance/worker/NuanceItemUpdateWorker.php
12256 views
<?php12final class NuanceItemUpdateWorker3extends NuanceWorker {45protected function doWork() {6$item_phid = $this->getTaskDataValue('itemPHID');78$lock = $this->newLock($item_phid);910$lock->lock(1);11try {12$item = $this->loadItem($item_phid);13$this->updateItem($item);14$this->routeItem($item);15$this->applyCommands($item);16} catch (Exception $ex) {17$lock->unlock();18throw $ex;19}2021$lock->unlock();22}2324private function updateItem(NuanceItem $item) {25$impl = $item->getImplementation();26if (!$impl->canUpdateItems()) {27return null;28}2930$viewer = $this->getViewer();3132$impl->setViewer($viewer);33$impl->updateItem($item);34}3536private function routeItem(NuanceItem $item) {37$status = $item->getStatus();38if ($status != NuanceItem::STATUS_ROUTING) {39return;40}4142$source = $item->getSource();4344// For now, always route items into the source's default queue.4546$item47->setQueuePHID($source->getDefaultQueuePHID())48->setStatus(NuanceItem::STATUS_OPEN)49->save();50}5152private function applyCommands(NuanceItem $item) {53$viewer = $this->getViewer();5455$commands = id(new NuanceItemCommandQuery())56->setViewer($viewer)57->withItemPHIDs(array($item->getPHID()))58->withStatuses(59array(60NuanceItemCommand::STATUS_ISSUED,61))62->execute();63$commands = msort($commands, 'getID');6465$this->executeCommandList($item, $commands);66}6768public function executeCommands(NuanceItem $item, array $commands) {69if (!$commands) {70return true;71}7273$item_phid = $item->getPHID();74$viewer = $this->getViewer();7576$lock = $this->newLock($item_phid);77try {78$lock->lock(1);79} catch (PhutilLockException $ex) {80return false;81}8283try {84$item = $this->loadItem($item_phid);8586// Reload commands now that we have a lock, to make sure we don't87// execute any commands twice by mistake.88$commands = id(new NuanceItemCommandQuery())89->setViewer($viewer)90->withIDs(mpull($commands, 'getID'))91->execute();9293$this->executeCommandList($item, $commands);94} catch (Exception $ex) {95$lock->unlock();96throw $ex;97}9899$lock->unlock();100101return true;102}103104private function executeCommandList(NuanceItem $item, array $commands) {105$viewer = $this->getViewer();106107$executors = NuanceCommandImplementation::getAllCommands();108foreach ($commands as $command) {109if ($command->getItemPHID() !== $item->getPHID()) {110throw new Exception(111pht('Trying to apply a command to the wrong item!'));112}113114if ($command->getStatus() !== NuanceItemCommand::STATUS_ISSUED) {115// Never execute commands which have already been issued.116continue;117}118119$command120->setStatus(NuanceItemCommand::STATUS_EXECUTING)121->save();122123try {124$command_key = $command->getCommand();125126$executor = idx($executors, $command_key);127if (!$executor) {128throw new Exception(129pht(130'Unable to execute command "%s": this command does not have '.131'a recognized command implementation.',132$command_key));133}134135$executor = clone $executor;136137$executor138->setActor($viewer)139->applyCommand($item, $command);140141$command142->setStatus(NuanceItemCommand::STATUS_DONE)143->save();144} catch (Exception $ex) {145$command146->setStatus(NuanceItemCommand::STATUS_FAILED)147->save();148149throw $ex;150}151}152}153154private function newLock($item_phid) {155$hash = PhabricatorHash::digestForIndex($item_phid);156$lock_key = "nuance.item.{$hash}";157return PhabricatorGlobalLock::newLock($lock_key);158}159160}161162163