From 8213f8d67d5a73b43b871d305e911e22b4144f79 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind@owncloud.com>
Date: Mon, 23 Feb 2015 15:25:59 +0100
Subject: [PATCH] Allow apps to determine which commands should be run
 synchronous based on traints

---
 lib/private/command/asyncbus.php | 59 +++++++++++++++++++++++++++++++-
 lib/public/command/ibus.php      |  7 ++++
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/lib/private/command/asyncbus.php b/lib/private/command/asyncbus.php
index fc9c85acc3f..084842fa6f1 100644
--- a/lib/private/command/asyncbus.php
+++ b/lib/private/command/asyncbus.php
@@ -21,6 +21,13 @@ class AsyncBus implements IBus {
 	 */
 	private $jobList;
 
+	/**
+	 * List of traits for command which require sync execution
+	 *
+	 * @var string[]
+	 */
+	private $syncTraits = [];
+
 	/**
 	 * @param \OCP\BackgroundJob\IJobList $jobList
 	 */
@@ -34,7 +41,31 @@ class AsyncBus implements IBus {
 	 * @param \OCP\Command\ICommand | callable $command
 	 */
 	public function push($command) {
-		$this->jobList->add($this->getJobClass($command), $this->serializeCommand($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();
+		}
 	}
 
 	/**
@@ -67,4 +98,30 @@ class AsyncBus implements IBus {
 			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 [];
+		}
+	}
 }
diff --git a/lib/public/command/ibus.php b/lib/public/command/ibus.php
index 707f8fd072d..bbb89ee04e6 100644
--- a/lib/public/command/ibus.php
+++ b/lib/public/command/ibus.php
@@ -15,4 +15,11 @@ interface IBus {
 	 * @param \OCP\Command\ICommand | callable $command
 	 */
 	public function push($command);
+
+	/**
+	 * Require all commands using a trait to be run synchronous
+	 *
+	 * @param string $trait
+	 */
+	public function requireSync($trait);
 }
-- 
GitLab