From 5c6079cd89376c7852f23f6e51b8fdd6425bd11e Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 15 Apr 2016 12:01:13 +0200 Subject: Move \OC\Command to PSR-4 --- lib/private/Command/AsyncBus.php | 140 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 lib/private/Command/AsyncBus.php (limited to 'lib/private/Command/AsyncBus.php') diff --git a/lib/private/Command/AsyncBus.php b/lib/private/Command/AsyncBus.php new file mode 100644 index 00000000000..eb692f9a8fb --- /dev/null +++ b/lib/private/Command/AsyncBus.php @@ -0,0 +1,140 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Command; + +use OCP\Command\IBus; +use OCP\Command\ICommand; +use SuperClosure\Serializer; + +/** + * Asynchronous command bus that uses the background job system as backend + */ +class AsyncBus implements IBus { + /** + * @var \OCP\BackgroundJob\IJobList + */ + private $jobList; + + /** + * List of traits for command which require sync execution + * + * @var string[] + */ + private $syncTraits = []; + + /** + * @param \OCP\BackgroundJob\IJobList $jobList + */ + function __construct($jobList) { + $this->jobList = $jobList; + } + + /** + * Schedule a command to be fired + * + * @param \OCP\Command\ICommand | callable $command + */ + public function push($command) { + if ($this->canRunAsync($command)) { + $this->jobList->add($this->getJobClass($command), $this->serializeCommand($command)); + } else { + $this->runCommand($command); + } + } + + /** + * Require all commands using a trait to be run synchronous + * + * @param string $trait + */ + public function requireSync($trait) { + $this->syncTraits[] = trim($trait, '\\'); + } + + /** + * @param \OCP\Command\ICommand | callable $command + */ + private function runCommand($command) { + if ($command instanceof ICommand) { + $command->handle(); + } else { + $command(); + } + } + + /** + * @param \OCP\Command\ICommand | callable $command + * @return string + */ + private function getJobClass($command) { + if ($command instanceof \Closure) { + return 'OC\Command\ClosureJob'; + } else if (is_callable($command)) { + return 'OC\Command\CallableJob'; + } else if ($command instanceof ICommand) { + return 'OC\Command\CommandJob'; + } else { + throw new \InvalidArgumentException('Invalid command'); + } + } + + /** + * @param \OCP\Command\ICommand | callable $command + * @return string + */ + private function serializeCommand($command) { + if ($command instanceof \Closure) { + $serializer = new Serializer(); + return $serializer->serialize($command); + } else if (is_callable($command) or $command instanceof ICommand) { + return serialize($command); + } else { + throw new \InvalidArgumentException('Invalid command'); + } + } + + /** + * @param \OCP\Command\ICommand | callable $command + * @return bool + */ + private function canRunAsync($command) { + $traits = $this->getTraits($command); + foreach ($traits as $trait) { + if (array_search($trait, $this->syncTraits) !== false) { + return false; + } + } + return true; + } + + /** + * @param \OCP\Command\ICommand | callable $command + * @return string[] + */ + private function getTraits($command) { + if ($command instanceof ICommand) { + return class_uses($command); + } else { + return []; + } + } +} -- cgit v1.2.3