Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
refs matomo-org#4610 make sure the fallback mode works in case async …
…is not supported
  • Loading branch information
tsteur committed Feb 11, 2014
1 parent f06a7a1 commit a2a586a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 16 deletions.
51 changes: 37 additions & 14 deletions core/CliMulti.php
Expand Up @@ -12,16 +12,32 @@

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);
Expand All @@ -39,18 +55,21 @@ public function request(array $piwikUrls)
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();
}
}
}

Expand Down Expand Up @@ -88,12 +107,12 @@ private function getResponse()

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;
}
}
Expand All @@ -112,21 +131,25 @@ private function generateCmdId($command)
*/
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();
}

foreach ($this->outputs as $output) {
$output->destroy();
}

$this->pids = array();
$this->outputs = array();
$this->processes = array();
$this->outputs = array();
}

}
4 changes: 2 additions & 2 deletions core/CliMulti/run.php
Expand Up @@ -43,8 +43,8 @@
$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;
Expand Down
9 changes: 9 additions & 0 deletions tests/PHPUnit/Integration/Core/CliMultiTest.php
Expand Up @@ -137,6 +137,15 @@ public function test_request_shouldBeAbleToRenderARegularPageInPiwik()
$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);
Expand Down

0 comments on commit a2a586a

Please sign in to comment.