8000 Add tests + fix coding style · symfony/symfony@68582dd · GitHub
[go: up one dir, main page]

Skip to content

Commit 68582dd

Browse files
Add tests + fix coding style
1 parent 9c2e708 commit 68582dd

File tree

3 files changed

+109
-7
lines changed

3 files changed

+109
-7
lines changed

src/Symfony/Component/Messenger/Command/ConsumeMessagesCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ protected function configure()
6464
6565
<info>php %command.full_name% <receiver-name> --limit=10</info>
6666
67-
Use the --memory-limit option to limit the memory consumed by the worker. Use PHP shorthand byte values [K, M or G]:
67+
Use the --memory-limit option to stop the worker if it exceeds a given memory usage limit. You can use shorthand byte values [K, M or G]:
6868
6969
<info>php %command.full_name% <receiver-name> --memory-limit=128M</info>
7070
EOF
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Tests\Transport\Enhancers;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
16+
use Symfony\Component\Messenger\Transport\Enhancers\MemoryLimitReceiver;
17+
use Symfony\Component\Messenger\Transport\ReceiverInterface;
18+
19+
class MemoryLimitReceiverTest extends TestCase
20+
{
21+
/**
22+
* @dataProvider memoryProvider
23+
*/
24+
public function testReceiverStopsWhenMemoryLimitExceeded($memoryUsage, $memoryLimit, $shouldStop)
25+
{
26+
$decoratedReceiver = $this->getMockBuilder(ReceiverToDecorate::class)
27+
->enableProxyingToOriginalMethods()
28+
->getMock();
29+
$decoratedReceiver->expects($this->once())->method('receive');
30+
if (true === $shouldStop) {
31+
$decoratedReceiver->expects($this->once())->method('stop');
32+
} else {
33+
$decoratedReceiver->expects($this->never())->method('stop');
34+
}
35+
36+
$memoryResolver = function () use ($memoryUsage) {
37+
return $memoryUsage;
38+
};
39+
40+
$memoryLimitReceiver = new MemoryLimitReceiver($decoratedReceiver, $memoryLimit, $memoryResolver);
41+
$memoryLimitReceiver->receive(function () {});
42+
}
43+
44+
public function memoryProvider()
45+
{
46+
return array(
47+
array(2048, 1024, true),
48+
array(1024, 1024, true),
49+
array(1024, 2048, false),
50+
array(129 * 1024, '128K', true),
51+
array(128 * 1024, '128K', true),
52+
array(127 * 1024, '128K', false),
53+
array(65 * 1024 * 1024, '64M', true),
54+
array(64 * 1024 * 1024, '64M', true),
55+
array(63 * 1024 * 1024, '64M', false),
56+
array(2 * 1024 * 1024 * 1024, '1G', true),
57+
array(1 * 1024 * 1024 * 1024, '1G', true),
58+
array(10 * 1024 * 1024, '1G', false),
59+
array(1 * 1024 * 1024 * 1024, '1M', true),
60+
array(1 * 1024 * 1024 * 1024, '1K', true),
61+
);
62+
}
63+
64+
/**
65+
* @dataProvider invalidMemoryLimitProvider
66+
* @expectedException \InvalidArgumentException
67+
*/
68+
public function testReceiverThrowsExceptionWithInvalidMemoryLimit($memoryLimit)
69+
{
70+
$decoratedReceiver = $this->createMock(ReceiverInterface::class);
71+
$memoryLimitReceiver = new MemoryLimitReceiver($decoratedReceiver, $memoryLimit);
72+
}
73+
74+
public function invalidMemoryLimitProvider()
75+
{
76+
return array(
77+
array('without_digit'), // string without digit
78+
array('1024X'), // bad unit
79+
array('128m'), // lowercase unit
80+
array('128 M'), // string with space
81+
);
82+
}
83+
}
84+
85+
class ReceiverToDecorate implements ReceiverInterface
86+
{
87+
public function receive(callable $handler): void
88+
{
89+
$handler(new DummyMessage('API'));
90+
}
91+
92+
public function stop(): void
93+
{
94+
}
95+
}

src/Symfony/Component/Messenger/Transport/Enhancers/MemoryLimitReceiver.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,24 @@ class MemoryLimitReceiver implements ReceiverInterface
2020
{
2121
private $decoratedReceiver;
2222
private $memoryLimit;
23+
private $memoryResolver;
2324

24-
public function __construct(ReceiverInterface $decoratedReceiver, string $memoryLimit)
25+
public function __construct(ReceiverInterface $decoratedReceiver, string $memoryLimit, callable $memoryResolver = null)
2526
{
2627
$this->decoratedReceiver = $decoratedReceiver;
2728
$this->memoryLimit = $this->convertToOctets($memoryLimit);
29+
$this->memoryResolver = $memoryResolver ?? function () {
30+
return \memory_get_usage();
31+
};
2832
}
2933

3034
public function receive(callable $handler): void
3135
{
3236
$this->decoratedReceiver->receive(function ($message) use ($handler) {
3337
$handler($message);
3438

35-
if (\memory_get_usage() >= $this->memoryLimit) {
39+
$memoryResolver = $this->memoryResolver;
40+
if ($memoryResolver() >= $this->memoryLimit) {
3641
$this->stop();
3742
}
3843
});
@@ -45,14 +50,16 @@ public function stop(): void
4550

4651
private function convertToOctets(string $size): int
4752
{
48-
if (\preg_match('/^(\d+)(.)$/', $size, $matches)) {
49-
if ($matches[2] == 'G') {
53+
if (\preg_match('/^(\d+)([G|M|K]*)$/', $size, $matches)) {
54+
if ('G' == $matches[2]) {
5055
$size = $matches[1] * 1024 * 1024 * 1024;
51-
} else if ($matches[2] == 'M') {
56+
} elseif ('M' == $matches[2]) {
5257
$size = $matches[1] * 1024 * 1024;
53-
} else if ($matches[2] == 'K') {
58+
} elseif ('K' == $matches[2]) {
5459
$size = $matches[1] * 1024;
5560
}
61+
} else {
62+
throw new \InvalidArgumentException('Invalid memory limit given.');
5663
}
5764

5865
return (int) $size;

0 commit comments

Comments
 (0)
0