From a2a586a0bf38c41fbd998bcb00cb7f081cd06555 Mon Sep 17 00:00:00 2001 From: Thomas Steur <thomas.steur@googlemail.com> Date: Tue, 11 Feb 2014 02:16:56 +0100 Subject: [PATCH] refs #4610 make sure the fallback mode works in case async is not supported --- core/CliMulti.php | 51 ++++++++++++++----- core/CliMulti/run.php | 4 +- .../PHPUnit/Integration/Core/CliMultiTest.php | 9 ++++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/core/CliMulti.php b/core/CliMulti.php index 0c9af59475..3688c254d2 100644 --- a/core/CliMulti.php +++ b/core/CliMulti.php @@ -12,16 +12,32 @@ use Piwik\CliMulti\Output; class CliMulti { + /** + * If set to true or false it will overwrite whether async is supported or not. + * + * @var null|bool + */ + public $supportsAsync = null; + /** * @var \Piwik\CliMulti\Process[] */ - private $pids = array(); + private $processes = array(); /** * @var \Piwik\CliMulti\Output[] */ private $outputs = array(); + /** + * It will request all given URLs in parallel (async) using the CLI and wait until all requests are finished. + * + * + * @param string[] $piwikUrls An array of urls, for instance: + * array('/index.php?module=API', '/?module=API', 'http://www.example.com?module=API') + * @return array The response of each URL in the same order as the URLs. The array can contain null values in case + * there was a problem with a request, for instance if the process died unexpected. + */ public function request(array $piwikUrls) { $this->start($piwikUrls); @@ -39,18 +55,21 @@ class CliMulti { private function start($piwikUrls) { foreach ($piwikUrls as $index => $url) { - $cmdId = $this->generateCmdId($url); - $pid = $cmdId . $index . '_cli_multi_pid'; - $output = $cmdId . $index . '_cli_multi_output'; + $cmdId = $this->generateCmdId($url); + $pid = $cmdId . $index . '_cli_multi_pid'; + $outputId = $cmdId . $index . '_cli_multi_output'; - $params = array('output' => $output, 'pid' => $pid); - $command = $this->buildCommand($url, $params); + $this->processes[] = new Process($pid); + $this->outputs[] = new Output($outputId); + + $command = $this->buildCommand($url, array('outputId' => $outputId, 'pid' => $pid)); $appendix = $this->supportsAsync() ? ' > /dev/null 2>&1 &' : ''; shell_exec($command . $appendix); - $this->pids[] = new Process($pid); - $this->outputs[] = new Output($output); + if (!$this->supportsAsync()) { + end($this->processes)->finishProcess(); + } } } @@ -88,12 +107,12 @@ class CliMulti { private function isFinished() { - foreach ($this->pids as $index => $pid) { - if (!$pid->hasStarted()) { + foreach ($this->processes as $index => $process) { + if (!$process->hasStarted()) { return false; } - if ($pid->isRunning() && !$this->outputs[$index]->exists()) { + if ($process->isRunning() && !$this->outputs[$index]->exists()) { return false; } } @@ -112,12 +131,16 @@ class CliMulti { */ private function supportsAsync() { + if (is_bool($this->supportsAsync)) { + return $this->supportsAsync; + } + return !SettingsServer::isWindows(); } private function cleanup() { - foreach ($this->pids as $pid) { + foreach ($this->processes as $pid) { $pid->finishProcess(); } @@ -125,8 +148,8 @@ class CliMulti { $output->destroy(); } - $this->pids = array(); - $this->outputs = array(); + $this->processes = array(); + $this->outputs = array(); } } diff --git a/core/CliMulti/run.php b/core/CliMulti/run.php index a06608f993..1accd71669 100644 --- a/core/CliMulti/run.php +++ b/core/CliMulti/run.php @@ -43,8 +43,8 @@ require_once PIWIK_INCLUDE_PATH . "/index.php"; $content = ob_get_contents(); ob_clean(); -if (!empty($_GET['output']) && \Piwik\Filesystem::isValidFilename($_GET['output'])) { - $cliMulti = new \Piwik\CliMulti\Output($_GET['output']); +if (!empty($_GET['outputId']) && \Piwik\Filesystem::isValidFilename($_GET['outputId'])) { + $cliMulti = new \Piwik\CliMulti\Output($_GET['outputId']); $cliMulti->write($content); } else { echo $content; diff --git a/tests/PHPUnit/Integration/Core/CliMultiTest.php b/tests/PHPUnit/Integration/Core/CliMultiTest.php index 1771467980..ac8d0f6c05 100644 --- a/tests/PHPUnit/Integration/Core/CliMultiTest.php +++ b/tests/PHPUnit/Integration/Core/CliMultiTest.php @@ -137,6 +137,15 @@ class Core_CliMultiTest extends IntegrationTestCase $this->assertTrue(false !== strpos($response[0], 'Widgetize the full dashboard')); } + public function test_shouldFallback_IfAsyncIsNotSupported() + { + $this->cliMulti->supportsAsync = false; + + $urls = $this->buildUrls('getPiwikVersion', 'getAnswerToLife', 'getPiwikVersion'); + + $this->assertRequestReturnsValidResponses($urls, array('getPiwikVersion', 'getAnswerToLife', 'getPiwikVersion')); + } + private function assertRequestReturnsValidResponses($urls, $expectedResponseIds) { $actualResponse = $this->cliMulti->request($urls); -- GitLab