Skip to content

Commit 22e5315

Browse files
authored
Merge pull request #467 from ramunasd/extension_niceness
[consumption] add process niceness extension
2 parents da52e3c + 70bfc63 commit 22e5315

File tree

7 files changed

+130
-6
lines changed

7 files changed

+130
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Enqueue\Consumption\Extension;
4+
5+
use Enqueue\Consumption\Context;
6+
use Enqueue\Consumption\EmptyExtensionTrait;
7+
use Enqueue\Consumption\ExtensionInterface;
8+
9+
class NicenessExtension implements ExtensionInterface
10+
{
11+
use EmptyExtensionTrait;
12+
13+
/**
14+
* @var int
15+
*/
16+
protected $niceness = 0;
17+
18+
/**
19+
* @param int $niceness
20+
*
21+
* @throws \InvalidArgumentException
22+
*/
23+
public function __construct($niceness)
24+
{
25+
if (false === is_int($niceness)) {
26+
throw new \InvalidArgumentException(sprintf(
27+
'Expected niceness value is int but got: "%s"',
28+
is_object($niceness) ? get_class($niceness) : gettype($niceness)
29+
));
30+
}
31+
32+
$this->niceness = $niceness;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function onStart(Context $context)
39+
{
40+
if (0 !== $this->niceness) {
41+
$changed = @proc_nice($this->niceness);
42+
if (!$changed) {
43+
throw new \InvalidArgumentException(sprintf(
44+
'Cannot change process niceness, got warning: "%s"',
45+
error_get_last()['message']
46+
));
47+
}
48+
}
49+
}
50+
}

pkg/enqueue/Symfony/Consumption/LimitsExtensionsCommandTrait.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Enqueue\Consumption\Extension\LimitConsumedMessagesExtension;
66
use Enqueue\Consumption\Extension\LimitConsumerMemoryExtension;
77
use Enqueue\Consumption\Extension\LimitConsumptionTimeExtension;
8+
use Enqueue\Consumption\Extension\NicenessExtension;
89
use Enqueue\Consumption\ExtensionInterface;
910
use Symfony\Component\Console\Input\InputInterface;
1011
use Symfony\Component\Console\Input\InputOption;
@@ -20,7 +21,8 @@ protected function configureLimitsExtensions()
2021
$this
2122
->addOption('message-limit', null, InputOption::VALUE_REQUIRED, 'Consume n messages and exit')
2223
->addOption('time-limit', null, InputOption::VALUE_REQUIRED, 'Consume messages during this time')
23-
->addOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Consume messages until process reaches this memory limit in MB');
24+
->addOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Consume messages until process reaches this memory limit in MB')
25+
->addOption('niceness', null, InputOption::VALUE_REQUIRED, 'Set process niceness');
2426
}
2527

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

63+
$niceness = $input->getOption('niceness');
64+
if ($niceness) {
65+
$extensions[] = new NicenessExtension($niceness);
66+
}
67+
6168
return $extensions;
6269
}
6370
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Enqueue\Tests\Consumption\Extension;
4+
5+
use Enqueue\Consumption\Context;
6+
use Enqueue\Consumption\Extension\NicenessExtension;
7+
use Interop\Queue\PsrConsumer;
8+
use Interop\Queue\PsrContext;
9+
use Interop\Queue\PsrProcessor;
10+
use PHPUnit\Framework\TestCase;
11+
use Psr\Log\LoggerInterface;
12+
13+
class NicenessExtensionTest extends TestCase
14+
{
15+
public function testCouldBeConstructedWithRequiredArguments()
16+
{
17+
new NicenessExtension(0);
18+
}
19+
20+
public function testShouldThrowExceptionOnInvalidArgument()
21+
{
22+
$this->expectException(\InvalidArgumentException::class);
23+
new NicenessExtension('1');
24+
}
25+
26+
public function testShouldThrowWarningOnInvalidArgument()
27+
{
28+
$this->expectException(\InvalidArgumentException::class);
29+
$this->expectExceptionMessage('proc_nice(): Only a super user may attempt to increase the priority of a process');
30+
31+
$extension = new NicenessExtension(-1);
32+
$extension->onStart($this->createContext());
33+
}
34+
35+
/**
36+
* @return Context
37+
*/
38+
protected function createContext()
39+
{
40+
$context = new Context($this->createMock(PsrContext::class));
41+
$context->setLogger($this->createMock(LoggerInterface::class));
42+
$context->setPsrConsumer($this->createMock(PsrConsumer::class));
43+
$context->setPsrProcessor($this->createMock(PsrProcessor::class));
44+
45+
return $context;
46+
}
47+
}

pkg/enqueue/Tests/Symfony/Client/ConsumeMessagesCommandTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,15 @@ public function testShouldHaveExpectedOptions()
6161

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

64-
$this->assertCount(7, $options);
64+
$this->assertCount(8, $options);
6565
$this->assertArrayHasKey('memory-limit', $options);
6666
$this->assertArrayHasKey('message-limit', $options);
6767
$this->assertArrayHasKey('time-limit', $options);
6868
$this->assertArrayHasKey('setup-broker', $options);
6969
$this->assertArrayHasKey('idle-timeout', $options);
7070
$this->assertArrayHasKey('receive-timeout', $options);
7171
$this->assertArrayHasKey('skip', $options);
72+
$this->assertArrayHasKey('niceness', $options);
7273
}
7374

7475
public function testShouldHaveExpectedArguments()

pkg/enqueue/Tests/Symfony/Consumption/ConsumeMessagesCommandTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ public function testShouldHaveExpectedOptions()
2929

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

32-
$this->assertCount(5, $options);
32+
$this->assertCount(6, $options);
3333
$this->assertArrayHasKey('memory-limit', $options);
3434
$this->assertArrayHasKey('message-limit', $options);
3535
$this->assertArrayHasKey('time-limit', $options);
3636
$this->assertArrayHasKey('idle-timeout', $options);
3737
$this->assertArrayHasKey('receive-timeout', $options);
38+
$this->assertArrayHasKey('niceness', $options);
3839
}
3940

4041
public function testShouldHaveExpectedAttributes()

pkg/enqueue/Tests/Symfony/Consumption/ContainerAwareConsumeMessagesCommandTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ public function testShouldHaveExpectedOptions()
3333

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

36-
$this->assertCount(6, $options);
36+
$this->assertCount(7, $options);
3737
$this->assertArrayHasKey('memory-limit', $options);
3838
$this->assertArrayHasKey('message-limit', $options);
3939
$this->assertArrayHasKey('time-limit', $options);
4040
$this->assertArrayHasKey('queue', $options);
4141
$this->assertArrayHasKey('idle-timeout', $options);
4242
$this->assertArrayHasKey('receive-timeout', $options);
43+
$this->assertArrayHasKey('niceness', $options);
4344
}
4445

4546
public function testShouldHaveExpectedAttributes()

pkg/enqueue/Tests/Symfony/Consumption/LimitsExtensionsCommandTraitTest.php

+19-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Enqueue\Consumption\Extension\LimitConsumedMessagesExtension;
66
use Enqueue\Consumption\Extension\LimitConsumerMemoryExtension;
77
use Enqueue\Consumption\Extension\LimitConsumptionTimeExtension;
8+
use Enqueue\Consumption\Extension\NicenessExtension;
89
use Enqueue\Tests\Symfony\Consumption\Mock\LimitsExtensionsCommand;
910
use PHPUnit\Framework\TestCase;
1011
use Symfony\Component\Console\Tester\CommandTester;
@@ -17,10 +18,11 @@ public function testShouldAddExtensionsOptions()
1718

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

20-
$this->assertCount(3, $options);
21+
$this->assertCount(4, $options);
2122
$this->assertArrayHasKey('memory-limit', $options);
2223
$this->assertArrayHasKey('message-limit', $options);
2324
$this->assertArrayHasKey('time-limit', $options);
25+
$this->assertArrayHasKey('niceness', $options);
2426
}
2527

2628
public function testShouldAddMessageLimitExtension()
@@ -57,7 +59,8 @@ public function testShouldAddTimeLimitExtension()
5759

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

6265
$command = new LimitsExtensionsCommand('name');
6366

@@ -104,4 +107,18 @@ public function testShouldAddThreeLimitExtensions()
104107
$this->assertInstanceOf(LimitConsumptionTimeExtension::class, $result[1]);
105108
$this->assertInstanceOf(LimitConsumerMemoryExtension::class, $result[2]);
106109
}
110+
111+
public function testShouldAddNicenessExtension()
112+
{
113+
$command = new LimitsExtensionsCommand('name');
114+
$tester = new CommandTester($command);
115+
$tester->execute([
116+
'--niceness' => 1,
117+
]);
118+
119+
$result = $command->getExtensions();
120+
$this->assertCount(1, $result);
121+
122+
$this->assertInstanceOf(NicenessExtension::class, $result[0]);
123+
}
107124
}

0 commit comments

Comments
 (0)