Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[consumption] add process niceness extension #467

Merged
merged 1 commit into from
Jul 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions pkg/enqueue/Consumption/Extension/NicenessExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Enqueue\Consumption\Extension;

use Enqueue\Consumption\Context;
use Enqueue\Consumption\EmptyExtensionTrait;
use Enqueue\Consumption\ExtensionInterface;

class NicenessExtension implements ExtensionInterface
{
use EmptyExtensionTrait;

/**
* @var int
*/
protected $niceness = 0;

/**
* @param int $niceness
*
* @throws \InvalidArgumentException
*/
public function __construct($niceness)
{
if (false === is_int($niceness)) {
throw new \InvalidArgumentException(sprintf(
'Expected niceness value is int but got: "%s"',
is_object($niceness) ? get_class($niceness) : gettype($niceness)
));
}

$this->niceness = $niceness;
}

/**
* {@inheritdoc}
*/
public function onStart(Context $context)
{
if (0 !== $this->niceness) {
$changed = @proc_nice($this->niceness);
if (!$changed) {
throw new \InvalidArgumentException(sprintf(
'Cannot change process niceness, got warning: "%s"',
error_get_last()['message']
));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Enqueue\Consumption\Extension\LimitConsumedMessagesExtension;
use Enqueue\Consumption\Extension\LimitConsumerMemoryExtension;
use Enqueue\Consumption\Extension\LimitConsumptionTimeExtension;
use Enqueue\Consumption\Extension\NicenessExtension;
use Enqueue\Consumption\ExtensionInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -20,7 +21,8 @@ protected function configureLimitsExtensions()
$this
->addOption('message-limit', null, InputOption::VALUE_REQUIRED, 'Consume n messages and exit')
->addOption('time-limit', null, InputOption::VALUE_REQUIRED, 'Consume messages during this time')
->addOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Consume messages until process reaches this memory limit in MB');
->addOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Consume messages until process reaches this memory limit in MB')
->addOption('niceness', null, InputOption::VALUE_REQUIRED, 'Set process niceness');
}

/**
Expand Down Expand Up @@ -58,6 +60,11 @@ protected function getLimitsExtensions(InputInterface $input, OutputInterface $o
$extensions[] = new LimitConsumerMemoryExtension($memoryLimit);
}

$niceness = $input->getOption('niceness');
if ($niceness) {
$extensions[] = new NicenessExtension($niceness);
}

return $extensions;
}
}
47 changes: 47 additions & 0 deletions pkg/enqueue/Tests/Consumption/Extension/NicenessExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Enqueue\Tests\Consumption\Extension;

use Enqueue\Consumption\Context;
use Enqueue\Consumption\Extension\NicenessExtension;
use Interop\Queue\PsrConsumer;
use Interop\Queue\PsrContext;
use Interop\Queue\PsrProcessor;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;

class NicenessExtensionTest extends TestCase
{
public function testCouldBeConstructedWithRequiredArguments()
{
new NicenessExtension(0);
}

public function testShouldThrowExceptionOnInvalidArgument()
{
$this->expectException(\InvalidArgumentException::class);
new NicenessExtension('1');
}

public function testShouldThrowWarningOnInvalidArgument()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('proc_nice(): Only a super user may attempt to increase the priority of a process');

$extension = new NicenessExtension(-1);
$extension->onStart($this->createContext());
}

/**
* @return Context
*/
protected function createContext()
{
$context = new Context($this->createMock(PsrContext::class));
$context->setLogger($this->createMock(LoggerInterface::class));
$context->setPsrConsumer($this->createMock(PsrConsumer::class));
$context->setPsrProcessor($this->createMock(PsrProcessor::class));

return $context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,15 @@ public function testShouldHaveExpectedOptions()

$options = $command->getDefinition()->getOptions();

$this->assertCount(7, $options);
$this->assertCount(8, $options);
$this->assertArrayHasKey('memory-limit', $options);
$this->assertArrayHasKey('message-limit', $options);
$this->assertArrayHasKey('time-limit', $options);
$this->assertArrayHasKey('setup-broker', $options);
$this->assertArrayHasKey('idle-timeout', $options);
$this->assertArrayHasKey('receive-timeout', $options);
$this->assertArrayHasKey('skip', $options);
$this->assertArrayHasKey('niceness', $options);
}

public function testShouldHaveExpectedArguments()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ public function testShouldHaveExpectedOptions()

$options = $command->getDefinition()->getOptions();

$this->assertCount(5, $options);
$this->assertCount(6, $options);
$this->assertArrayHasKey('memory-limit', $options);
$this->assertArrayHasKey('message-limit', $options);
$this->assertArrayHasKey('time-limit', $options);
$this->assertArrayHasKey('idle-timeout', $options);
$this->assertArrayHasKey('receive-timeout', $options);
$this->assertArrayHasKey('niceness', $options);
}

public function testShouldHaveExpectedAttributes()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ public function testShouldHaveExpectedOptions()

$options = $command->getDefinition()->getOptions();

$this->assertCount(6, $options);
$this->assertCount(7, $options);
$this->assertArrayHasKey('memory-limit', $options);
$this->assertArrayHasKey('message-limit', $options);
$this->assertArrayHasKey('time-limit', $options);
$this->assertArrayHasKey('queue', $options);
$this->assertArrayHasKey('idle-timeout', $options);
$this->assertArrayHasKey('receive-timeout', $options);
$this->assertArrayHasKey('niceness', $options);
}

public function testShouldHaveExpectedAttributes()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Enqueue\Consumption\Extension\LimitConsumedMessagesExtension;
use Enqueue\Consumption\Extension\LimitConsumerMemoryExtension;
use Enqueue\Consumption\Extension\LimitConsumptionTimeExtension;
use Enqueue\Consumption\Extension\NicenessExtension;
use Enqueue\Tests\Symfony\Consumption\Mock\LimitsExtensionsCommand;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
Expand All @@ -17,10 +18,11 @@ public function testShouldAddExtensionsOptions()

$options = $trait->getDefinition()->getOptions();

$this->assertCount(3, $options);
$this->assertCount(4, $options);
$this->assertArrayHasKey('memory-limit', $options);
$this->assertArrayHasKey('message-limit', $options);
$this->assertArrayHasKey('time-limit', $options);
$this->assertArrayHasKey('niceness', $options);
}

public function testShouldAddMessageLimitExtension()
Expand Down Expand Up @@ -57,7 +59,8 @@ public function testShouldAddTimeLimitExtension()

public function testShouldThrowExceptionIfTimeLimitExpressionIsNotValid()
{
$this->setExpectedException(\Exception::class, 'Failed to parse time string (time is not valid) at position');
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Failed to parse time string (time is not valid) at position');

$command = new LimitsExtensionsCommand('name');

Expand Down Expand Up @@ -104,4 +107,18 @@ public function testShouldAddThreeLimitExtensions()
$this->assertInstanceOf(LimitConsumptionTimeExtension::class, $result[1]);
$this->assertInstanceOf(LimitConsumerMemoryExtension::class, $result[2]);
}

public function testShouldAddNicenessExtension()
{
$command = new LimitsExtensionsCommand('name');
$tester = new CommandTester($command);
$tester->execute([
'--niceness' => 1,
]);

$result = $command->getExtensions();
$this->assertCount(1, $result);

$this->assertInstanceOf(NicenessExtension::class, $result[0]);
}
}