Queue improvements

This commit is contained in:
Dmitry Khomutov 2017-02-01 21:53:31 +07:00
parent c1d8beb5f0
commit 7e735bbb3b
No known key found for this signature in database
GPG key ID: 7EB36C9576F9ECB9
18 changed files with 65 additions and 43 deletions

View file

@ -19,9 +19,10 @@ php-censor:
from_address: 'no-reply@php-censor.local' from_address: 'no-reply@php-censor.local'
smtp_address: smtp_address:
queue: queue:
host: localhost use_queue: true
name: php-censor-queue host: localhost
lifetime: 600 name: php-censor-queue
lifetime: 600
github: github:
token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
comments: comments:

View file

@ -190,7 +190,7 @@ class Builder implements LoggerAwareInterface
$previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch()); $previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch());
$previous_state = Build::STATUS_NEW; $previous_state = Build::STATUS_PENDING;
if ($previous_build) { if ($previous_build) {
$previous_state = $previous_build->getStatus(); $previous_state = $previous_build->getStatus();
@ -223,7 +223,7 @@ class Builder implements LoggerAwareInterface
} else { } else {
$this->pluginExecutor->executePlugins($this->config, 'failure'); $this->pluginExecutor->executePlugins($this->config, 'failure');
if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_NEW) { if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_PENDING) {
$this->pluginExecutor->executePlugins($this->config, 'broken'); $this->pluginExecutor->executePlugins($this->config, 'broken');
} }
} }

View file

@ -43,6 +43,7 @@ class InstallCommand extends Command
$this $this
->setName('php-censor:install') ->setName('php-censor:install')
->addOption('url', null, InputOption::VALUE_OPTIONAL, Lang::get('installation_url')) ->addOption('url', null, InputOption::VALUE_OPTIONAL, Lang::get('installation_url'))
->addOption('db-type', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host')) ->addOption('db-type', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host'))
->addOption('db-host', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host')) ->addOption('db-host', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host'))
@ -54,9 +55,10 @@ class InstallCommand extends Command
->addOption('admin-pass', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_pass')) ->addOption('admin-pass', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_pass'))
->addOption('admin-mail', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_email')) ->addOption('admin-mail', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_email'))
->addOption('config-path', null, InputOption::VALUE_OPTIONAL, Lang::get('config_path'), $defaultPath) ->addOption('config-path', null, InputOption::VALUE_OPTIONAL, Lang::get('config_path'), $defaultPath)
->addOption('queue-disabled', null, InputOption::VALUE_NONE, 'Don\'t ask for queue details') ->addOption('queue-use', null, InputOption::VALUE_OPTIONAL, 'Don\'t ask for queue details')
->addOption('queue-server', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue server hostname') ->addOption('queue-host', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue server hostname')
->addOption('queue-name', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue name') ->addOption('queue-name', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue name')
->setDescription(Lang::get('install_app')); ->setDescription(Lang::get('install_app'));
} }
@ -250,45 +252,53 @@ class InstallCommand extends Command
$config['per_page'] = 10; $config['per_page'] = 10;
$config['url'] = $url; $config['url'] = $url;
$config['queue'] = $this->getQueueInformation($input, $output, $helper); $config['queue'] = $this->getQueueInformation($input, $output);
return $config; return $config;
} }
/** /**
* If the user wants to use a queue, get the necessary details. * If the user wants to use a queue, get the necessary details.
*
* @param InputInterface $input * @param InputInterface $input
* @param OutputInterface $output * @param OutputInterface $output
* @param QuestionHelper $helper
* @return array * @return array
*/ */
protected function getQueueInformation(InputInterface $input, OutputInterface $output, QuestionHelper $helper) protected function getQueueInformation(InputInterface $input, OutputInterface $output)
{ {
if ($input->getOption('queue-disabled')) { $skipQueueConfig = [
return null; 'queue-use' => false,
];
if (!$input->getOption('queue-use')) {
return $skipQueueConfig;
} }
$rtn = []; $queueConfig = [
'queue-use' => true,
];
$helper = $this->getHelper('question'); /** @var $helper QuestionHelper */
$question = new ConfirmationQuestion('Use beanstalkd to manage build queue? ', true); $helper = $this->getHelper('question');
$question = new ConfirmationQuestion('Use beanstalkd to manage build queue? ', false);
if (!$helper->ask($input, $output, $question)) { if (!$helper->ask($input, $output, $question)) {
$output->writeln('<error>Skipping beanstalkd configuration.</error>'); $output->writeln('<error>Skipping beanstalkd configuration.</error>');
return null;
return $skipQueueConfig;
} }
if (!$rtn['host'] = $input->getOption('queue-server')) { if (!$queueConfig['host'] = $input->getOption('queue-host')) {
$questionQueue = new Question('Enter your beanstalkd hostname [localhost]: ', 'localhost'); $questionQueue = new Question('Enter your beanstalkd hostname [localhost]: ', 'localhost');
$rtn['host'] = $helper->ask($input, $output, $questionQueue); $queueConfig['host'] = $helper->ask($input, $output, $questionQueue);
} }
if (!$rtn['name'] = $input->getOption('queue-name')) { if (!$queueConfig['name'] = $input->getOption('queue-name')) {
$questionName = new Question('Enter the queue (tube) name to use [php-censor-queue]: ', 'php-censor-queue'); $questionName = new Question('Enter the queue (tube) name to use [php-censor-queue]: ', 'php-censor-queue');
$rtn['name'] = $helper->ask($input, $output, $questionName); $queueConfig['name'] = $helper->ask($input, $output, $questionName);
} }
return $rtn; return $queueConfig;
} }
/** /**

View file

@ -87,7 +87,7 @@ class PollCommand extends Command
$build = new Build(); $build = new Build();
$build->setProjectId($project->getId()); $build->setProjectId($project->getId());
$build->setCommitId($last_commit); $build->setCommitId($last_commit);
$build->setStatus(Build::STATUS_NEW); $build->setStatus(Build::STATUS_PENDING);
$build->setBranch($project->getBranch()); $build->setBranch($project->getBranch());
$build->setCreated(new \DateTime()); $build->setCreated(new \DateTime());
$build->setCommitMessage($message); $build->setCommitMessage($message);

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHPCI - Continuous Integration for PHP * PHPCI - Continuous Integration for PHP
* *

View file

@ -15,6 +15,7 @@ use PHPCensor\Helper\Lang;
use PHPCensor\Logging\BuildDBLogHandler; use PHPCensor\Logging\BuildDBLogHandler;
use PHPCensor\Logging\LoggedBuildContextTidier; use PHPCensor\Logging\LoggedBuildContextTidier;
use PHPCensor\Logging\OutputLogHandler; use PHPCensor\Logging\OutputLogHandler;
use PHPCensor\Store\BuildStore;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
@ -66,7 +67,7 @@ class RunCommand extends Command
} }
/** /**
* Pulls all pending builds from the database and runs them. * Pulls all pending builds from the database or queue and runs them.
*/ */
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
@ -80,7 +81,7 @@ class RunCommand extends Command
); );
} }
// Allow PHPCI to run in "debug mode" // Allow PHP Censor to run in "debug mode"
if ($input->hasOption('debug') && $input->getOption('debug')) { if ($input->hasOption('debug') && $input->getOption('debug')) {
$output->writeln('<comment>Debug mode enabled.</comment>'); $output->writeln('<comment>Debug mode enabled.</comment>');
define('DEBUG_MODE', true); define('DEBUG_MODE', true);
@ -90,8 +91,11 @@ class RunCommand extends Command
$this->logger->pushProcessor(new LoggedBuildContextTidier()); $this->logger->pushProcessor(new LoggedBuildContextTidier());
$this->logger->addInfo(Lang::get('finding_builds')); $this->logger->addInfo(Lang::get('finding_builds'));
$store = Factory::getStore('Build');
$result = $store->getByStatus(0, $this->maxBuilds); /** @var BuildStore $store */
$store = Factory::getStore('Build');
$result = $store->getByStatus(Build::STATUS_PENDING, $this->maxBuilds);
$this->logger->addInfo(Lang::get('found_n_builds', count($result['items']))); $this->logger->addInfo(Lang::get('found_n_builds', count($result['items'])));
$builds = 0; $builds = 0;
@ -147,7 +151,7 @@ class RunCommand extends Command
{ {
/** @var \PHPCensor\Store\BuildStore $store */ /** @var \PHPCensor\Store\BuildStore $store */
$store = Factory::getStore('Build'); $store = Factory::getStore('Build');
$running = $store->getByStatus(1); $running = $store->getByStatus(Build::STATUS_RUNNING);
$rtn = []; $rtn = [];
$timeout = Config::getInstance()->get('php-censor.build.failed_after', 1800); $timeout = Config::getInstance()->get('php-censor.build.failed_after', 1800);

View file

@ -272,7 +272,7 @@ class BuildController extends Controller
public function ajaxQueue() public function ajaxQueue()
{ {
$rtn = [ $rtn = [
'pending' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_NEW)), 'pending' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_PENDING)),
'running' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_RUNNING)), 'running' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_RUNNING)),
]; ];

View file

@ -21,7 +21,7 @@ use Symfony\Component\Yaml\Parser as YamlParser;
*/ */
class Build extends BuildBase class Build extends BuildBase
{ {
const STATUS_NEW = 0; const STATUS_PENDING = 0;
const STATUS_RUNNING = 1; const STATUS_RUNNING = 1;
const STATUS_SUCCESS = 2; const STATUS_SUCCESS = 2;
const STATUS_FAILED = 3; const STATUS_FAILED = 3;

View file

@ -105,7 +105,7 @@ class BuildStatusService
{ {
if (in_array($this->build->getStatus(), $this->finishedStatusIds)) { if (in_array($this->build->getStatus(), $this->finishedStatusIds)) {
return 'Sleeping'; return 'Sleeping';
} elseif ($this->build->getStatus() == Build::STATUS_NEW) { } elseif ($this->build->getStatus() == Build::STATUS_PENDING) {
return 'Pending'; return 'Pending';
} elseif ($this->build->getStatus() == Build::STATUS_RUNNING) { } elseif ($this->build->getStatus() == Build::STATUS_RUNNING) {
return 'Building'; return 'Building';

View file

@ -85,7 +85,14 @@ class BuildStoreBase extends Store
/** /**
* Get multiple Build by Status. * Get multiple Build by Status.
*
* @param $value
* @param int $limit
* @param string $useConnection
*
* @return array * @return array
*
* @throws HttpException
*/ */
public function getByStatus($value, $limit = 1000, $useConnection = 'read') public function getByStatus($value, $limit = 1000, $useConnection = 'read')
{ {
@ -93,7 +100,6 @@ class BuildStoreBase extends Store
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
} }
$query = 'SELECT * FROM {{build}} WHERE {{status}} = :status LIMIT :limit'; $query = 'SELECT * FROM {{build}} WHERE {{status}} = :status LIMIT :limit';
$stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt = Database::getConnection($useConnection)->prepareCommon($query);
$stmt->bindValue(':status', $value); $stmt->bindValue(':status', $value);

View file

@ -10,7 +10,7 @@
<h4> <h4>
<?php print $build->getProject()->getTitle(); ?> <?php print $build->getProject()->getTitle(); ?>
<?php if ($build->getStatus() == \PHPCensor\Model\Build::STATUS_NEW): ?> <?php if ($build->getStatus() == \PHPCensor\Model\Build::STATUS_PENDING): ?>
<small class="pull-right"><?php Lang::out('created_x', $build->getCreated()->format('H:i')); ?></small> <small class="pull-right"><?php Lang::out('created_x', $build->getCreated()->format('H:i')); ?></small>
<?php elseif ($build->getStatus() == \PHPCensor\Model\Build::STATUS_RUNNING): ?> <?php elseif ($build->getStatus() == \PHPCensor\Model\Build::STATUS_RUNNING): ?>
<small class="pull-right"><?php Lang::out('started_x', $build->getStarted()->format('H:i')); ?></small> <small class="pull-right"><?php Lang::out('started_x', $build->getStarted()->format('H:i')); ?></small>

View file

@ -5,7 +5,7 @@
<?php <?php
foreach ($builds as $build): foreach ($builds as $build):
switch ($build->getStatus()) { switch ($build->getStatus()) {
case \PHPCensor\Model\Build::STATUS_NEW: case \PHPCensor\Model\Build::STATUS_PENDING:
$updated = $build->getCreated(); $updated = $build->getCreated();
$label = Lang::get('pending'); $label = Lang::get('pending');
$color = 'blue'; $color = 'blue';

View file

@ -31,7 +31,7 @@
<?php <?php
foreach ($builds as $build): foreach ($builds as $build):
switch ($build->getStatus()) { switch ($build->getStatus()) {
case \PHPCensor\Model\Build::STATUS_NEW: case \PHPCensor\Model\Build::STATUS_PENDING:
$updated = $build->getCreated(); $updated = $build->getCreated();
$label = Lang::get('pending'); $label = Lang::get('pending');
$color = 'blue'; $color = 'blue';

View file

@ -59,8 +59,8 @@ class BuildWorker
*/ */
public function __construct($host, $queue) public function __construct($host, $queue)
{ {
$this->host = $host; $this->host = $host;
$this->queue = $queue; $this->queue = $queue;
$this->pheanstalk = new Pheanstalk($this->host); $this->pheanstalk = new Pheanstalk($this->host);
} }

View file

@ -107,7 +107,7 @@ class InstallCommandTest extends \PHPUnit_Framework_TestCase
'--admin-name' => 'admin', '--admin-name' => 'admin',
'--admin-pass' => 'admin-password', '--admin-pass' => 'admin-password',
'--url' => 'http://php-censor.local', '--url' => 'http://php-censor.local',
'--queue-disabled' => null, '--queue-use' => null,
]; ];
if (!is_null($exclude)) { if (!is_null($exclude)) {

View file

@ -43,7 +43,7 @@ class BuildTest extends \PHPUnit_Framework_TestCase
public function testExecute_TestIsSuccessful() public function testExecute_TestIsSuccessful()
{ {
$build = new Build(); $build = new Build();
$build->setStatus(Build::STATUS_NEW); $build->setStatus(Build::STATUS_PENDING);
$this->assertFalse($build->isSuccessful()); $this->assertFalse($build->isSuccessful());
$build->setStatus(Build::STATUS_RUNNING); $build->setStatus(Build::STATUS_RUNNING);

View file

@ -50,7 +50,7 @@ class BuildServiceTest extends \PHPUnit_Framework_TestCase
$returnValue = $this->testedService->createBuild($project); $returnValue = $this->testedService->createBuild($project);
$this->assertEquals(101, $returnValue->getProjectId()); $this->assertEquals(101, $returnValue->getProjectId());
$this->assertEquals(Build::STATUS_NEW, $returnValue->getStatus()); $this->assertEquals(Build::STATUS_PENDING, $returnValue->getStatus());
$this->assertNull($returnValue->getStarted()); $this->assertNull($returnValue->getStarted());
$this->assertNull($returnValue->getFinished()); $this->assertNull($returnValue->getFinished());
$this->assertNull($returnValue->getLog()); $this->assertNull($returnValue->getLog());
@ -108,7 +108,7 @@ class BuildServiceTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($build->getProjectId(), $returnValue->getProjectId()); $this->assertEquals($build->getProjectId(), $returnValue->getProjectId());
$this->assertEquals($build->getCommitId(), $returnValue->getCommitId()); $this->assertEquals($build->getCommitId(), $returnValue->getCommitId());
$this->assertNotEquals($build->getStatus(), $returnValue->getStatus()); $this->assertNotEquals($build->getStatus(), $returnValue->getStatus());
$this->assertEquals(Build::STATUS_NEW, $returnValue->getStatus()); $this->assertEquals(Build::STATUS_PENDING, $returnValue->getStatus());
$this->assertNull($returnValue->getLog()); $this->assertNull($returnValue->getLog());
$this->assertEquals($build->getBranch(), $returnValue->getBranch()); $this->assertEquals($build->getBranch(), $returnValue->getBranch());
$this->assertNotEquals($build->getCreated(), $returnValue->getCreated()); $this->assertNotEquals($build->getCreated(), $returnValue->getCreated());

View file

@ -80,7 +80,7 @@ class BuildStatusServiceTest extends \PHPUnit_Framework_TestCase
'previousBuild' => null, 'previousBuild' => null,
], ],
'5' => [ '5' => [
'status' => Build::STATUS_NEW, 'status' => Build::STATUS_PENDING,
'id' => 1000, 'id' => 1000,
'finishDateTime' => '2014-12-25 21:12:21', 'finishDateTime' => '2014-12-25 21:12:21',
'previousBuild' => 3, 'previousBuild' => 3,