Skip to content

Commit 73a134c

Browse files
author
Gaetano Giunta
committed
fix: mariadb client perceived as failed
1 parent 72e0cf7 commit 73a134c

File tree

7 files changed

+72
-12
lines changed

7 files changed

+72
-12
lines changed

TODO.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
- fix auth problems with mysql 8.0
22

33
- worker: improve sql execution cmd:
4-
+ fix: why does mariadb cli command does return -1 as exit code ?
54
+ allow it to take sql snippet from file
65
+ allow it to pick a set of desired servers
76
+ at end show results + time & mem taken for each db
@@ -41,6 +40,9 @@
4140

4241
- postgresql: move stats_temp_directory to /tmpfs
4342

43+
- worker: allow to run tests which consist of executing sql/sh/php payloads in parallel with N threads against each server.
44+
This would allow to find out if any code construct has _scalability_ problems on a given db version
45+
4446
- worker: add phpbench as dependency
4547

4648
- allow to easily set up either prod/public or dev/private stacks via a parameter in .env

WHATSNEW.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Version 0.2 (unreleased)
2+
------------------------
3+
4+
- Fixed: sql commands executed against mariadb would be reported as failed
5+
6+
7+
Version 0.1
8+
-----------
9+
10+
A preview release more than anything else.
11+
12+
What works:
13+
14+
- all current versions of MariaDB, MySQL and PostgreSQL are installed and available (MySQL 8.0 has a config problem with login auth though)
15+
- a cli script is available that runs a SQL snippet against all databases
16+
17+
What does not work:
18+
19+
- everything else

app/src/Command/SqlExecute.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Symfony\Component\Console\Input\InputInterface;
66
use Symfony\Component\Console\Output\OutputInterface;
77
use Symfony\Component\Console\Input\InputOption;
8-
use Symfony\Component\Process\Process;
8+
use Db3v4l\Util\Process;
99
use Symfony\Component\Yaml\Yaml;
1010
use Db3v4l\Service\DatabaseConfigurationManager;
1111
use Db3v4l\Service\SqlExecutorFactory;
@@ -41,6 +41,7 @@ protected function configure()
4141
//->addOption('output-type', null, InputOption::VALUE_REQUIRED, 'The format for the output: text, json or yml', 'text')
4242
->addOption('timeout', null, InputOption::VALUE_REQUIRED, 'The maximum time to wait for execution (secs)', 600)
4343
->addOption('max-parallel', null, InputOption::VALUE_REQUIRED, 'The maximum number of processes to run in parallel', 16)
44+
->addOption('dont-force-enabled-sigchild', null, InputOption::VALUE_NONE, "When using a separate php process to run each sql command, do not force Symfony to believe that php was compiled with --enable-sigchild option")
4445
;
4546
}
4647

@@ -54,28 +55,45 @@ protected function execute(InputInterface $input, OutputInterface $output)
5455
{
5556
$start = microtime(true);
5657

58+
// as per https://www.php.net/manual/en/function.ignore-user-abort.php: for cli scripts, it is probably a good idea
59+
// to use ignore_user_abort
60+
ignore_user_abort(true);
61+
5762
$this->setOutput($output);
5863
$this->setVerbosity($output->getVerbosity());
5964

6065
$dbList = $this->dbManager->listDatabases();
6166
$sql = $input->getOption('sql');
6267
$timeout = $input->getOption('timeout');
6368
$maxParallel = $input->getOption('max-parallel');
69+
$dontForceSigchildEnabled = $input->getOption('dont-force-enabled-sigchild');
6470

6571
if ($sql === '') {
6672
throw new \Exception("Please provide an sql command/snippted to be executed");
6773
}
6874

75+
// On Debian, which we use by default, SF has troubles understanding that php was compiled with --enable-sigchild
76+
// We thus force it, but give end users an option to disable this
77+
// For more details, see comment 12 at https://bugs.launchpad.net/ubuntu/+source/php5/+bug/516061
78+
if (!$dontForceSigchildEnabled) {
79+
80+
Process::forceSigchildEnabled(true);
81+
}
82+
6983
/** @var Process[] $processes */
7084
$processes = [];
7185
foreach ($dbList as $dbName) {
7286
$dbConnectionSpec = $this->dbManager->getDatabaseConnectionSpecification($dbName);
73-
$processes[$dbName] = $this->executorFactory->createForkedExecutor($dbConnectionSpec)->getProcess($sql);
87+
$process = $this->executorFactory->createForkedExecutor($dbConnectionSpec)->getProcess($sql);
88+
89+
$process->setTimeout($timeout);
90+
91+
$processes[$dbName] = $process;
7492
}
7593

7694
$this->writeln("Starting parallel execution...");
7795

78-
$this->processManager->runParallel($processes, $maxParallel, $timeout, 100, array($this, 'onSubProcessOutput'));
96+
$this->processManager->runParallel($processes, $maxParallel, 100, array($this, 'onSubProcessOutput'));
7997

8098
$failed = 0;
8199
$succeeded = 0;

app/src/Service/ProcessManager.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ class ProcessManager
1313
/**
1414
* @param Process[] $processes
1515
* @param int $maxParallel
16-
* @param int $timeout secs
1716
* @param int $poll microseconds
1817
* @param Callable $callback takes 4 args: $type, $buffer, $processIndex, $process
1918
*/
20-
public function runParallel(array $processes, $maxParallel, $timeout = 86400, $poll = 1000, $callback = null)
19+
public function runParallel(array $processes, $maxParallel, $poll = 1000, $callback = null)
2120
{
2221
$this->validateProcesses($processes);
2322
// do not modify the object pointers in the argument, copy to local working variable
@@ -29,7 +28,6 @@ public function runParallel(array $processes, $maxParallel, $timeout = 86400, $p
2928
$currentProcesses = array_splice($processesQueue, 0, $maxParallel);
3029
// start the initial stack of processes
3130
foreach ($currentProcesses as $idx => $process) {
32-
$process->setTimeout($timeout);
3331
$process->start(function ($type, $buffer) use ($callback, $idx, $process) {
3432
if ($callback) {
3533
$callback($type, $buffer, $idx, $process);
@@ -73,4 +71,4 @@ protected function validateProcesses(array $processes)
7371
}
7472
}
7573
}
76-
}
74+
}

app/src/Service/SqlExecutor/Forked/Doctrine.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace Db3v4l\Service\SqlExecutor\Forked;
44

5-
use Symfony\Component\Process\Process;
65
use Db3v4l\API\Interfaces\ForkedSqlExecutor;
6+
use Db3v4l\Util\Process;
77

88
class Doctrine extends ForkedExecutor implements ForkedSqlExecutor
99
{
@@ -15,4 +15,4 @@ public function getProcess($sql)
1515
{
1616
throw new \RuntimeException('TO BE IMPLEMENTED');
1717
}
18-
}
18+
}

app/src/Service/SqlExecutor/Forked/NativeClient.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
namespace Db3v4l\Service\SqlExecutor\Forked;
44

5-
use Symfony\Component\Process\Process;
6-
75
use Db3v4l\API\Interfaces\ForkedSqlExecutor;
6+
use Db3v4l\Util\Process;
87

98
class NativeClient extends ForkedExecutor implements ForkedSqlExecutor
109
{

app/src/Util/Process.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Db3v4l\Util;
4+
5+
use Symfony\Component\Process\Process as BaseProcess;
6+
7+
class Process extends BaseProcess
8+
{
9+
static $forceSigchildEnabled = null;
10+
11+
public static function forceSigchildEnabled($force)
12+
{
13+
self::$forceSigchildEnabled = (bool) $force;
14+
}
15+
16+
protected function isSigchildEnabled()
17+
{
18+
if (null !== self::$forceSigchildEnabled) {
19+
return self::$forceSigchildEnabled;
20+
}
21+
22+
return parent::isSigchildEnabled();
23+
}
24+
}

0 commit comments

Comments
 (0)