Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Messenger] Add a memory limit option forConsumeMessagesCommand#26975

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

@sdelicata
Copy link
Contributor

QA
Branch?master for features
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
LicenseMIT

New feature to add a memory limit option to the ConsumeMessagesCommand.

bin/console messenger:consume-messages <receiver-name> -m 128

abellion, Koc, yceruto, and andreybolonin reacted with thumbs up emoji
Use the --memory option to limit the memory consumed by the worker:
<info>php %command.full_name% <receiver-name> --memory=128</info>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Would personally call it--memory-limit to be the same as in php. It's also not exactly clear that it's in M. Would it be an idea to useG, M, K support here, just like with php?

abellion and yceruto reacted with thumbs up emoji
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Good idea, I did it

@nicolas-grekasnicolas-grekas added this to the4.1 milestoneApr 18, 2018
@sroze
Copy link
Contributor

sroze commentedApr 18, 2018
edited
Loading

Same as for the other PR, could you have some tests? :)

<info>php %command.full_name% <receiver-name> --limit=10</info>
Use the --memory-limit option to limit the memory consumed by the worker. Use PHP shorthand byte values [K, M or G]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

- Use the --memory-limit option to limit the memory consumed by the worker. Use PHP shorthand byte values [K, M or G]:+ 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]:

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Changed


privatefunctionconvertToOctets(string$size):int
{
if (\preg_match('/^(\d+)(.)$/',$size,$matches)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'd be stricter than.. Maybe just(G|M|K) and throw an exception if nothing is recognized to prevent any issue.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Done

@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch 2 times, most recently from5a8f69f to68582ddCompareApril 19, 2018 15:57
thrownew \InvalidArgumentException('Invalid memory limit given.');
}

return (int)$size;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Could(int) casting be removed? seems unnecessary after\d+ and... * 1024 ....

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

True, unnecessary anymore, thx


publicfunctionstop():void
{
$this->decoratedReceiver->stop();
Copy link
Member

@ycerutoycerutoApr 19, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I wondering if should we throw some kind of exception or log after that? I mean, right now it's stopped silently, how can we know if it was finished by memory limit or because it has received all messages?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@yceruto Good idea.
@sroze Did you already imagined such a notification mechanism?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't see any reason throwing an exception for this. What is your use-case? Do you need to know this for something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actually, it is probably a good idea to log such behavior (no exception). Maybe an optionalLoggerInterface argument that would be called withinfo when that happens? (note that it wouldn't be on this line but when you actually detect the memory usage line 41 of this line).

@lyrixx any PoV on the logging level?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I disagree exception too, but the optional LoggerInterface is a good idea

{
$this->decoratedReceiver =$decoratedReceiver;
$this->memoryLimit =$this->convertToOctets($memoryLimit);
$this->memoryResolver =$memoryResolver ??function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

?: ?

publicfunctionmemoryProvider()
{
returnarray(
array(2048,1024,true),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

yield?

}
}

class ReceiverToDecorateimplements ReceiverInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Could you instead usetheCallbackReceiver (that needs to be moved to a proper file) ?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Of course

$size =$matches[1] *1024;
}
}else {
thrownew \InvalidArgumentException('Invalid memory limit given.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Can you throw first to reduce a depth level? i.e.if (!\preg_match(...)) { thow /* ... */; }


publicfunctionstop():void
{
$this->decoratedReceiver->stop();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actually, it is probably a good idea to log such behavior (no exception). Maybe an optionalLoggerInterface argument that would be called withinfo when that happens? (note that it wouldn't be on this line but when you actually detect the memory usage line 41 of this line).

@lyrixx any PoV on the logging level?

@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch 2 times, most recently from0d2d782 toc1236ceCompareApril 20, 2018 12:17
if ($memoryResolver() >=$this->memoryLimit) {
$this->stop();
if ($this->logger) {
$this->logger->info('Receiver stopped due to memory limit exceeded.');
Copy link
Contributor

@srozesrozeApr 20, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

$this->logger !==null &&$this->logger->info('Receiver stopped due to memory limit of {limit} exceeded',array('limit' =>$this->memoryLimit));

{
if (!\preg_match('/^(\d+)([G|M|K]*)$/',$size,$matches)) {
thrownew \InvalidArgumentException('Invalid memory limit given.');
}else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Well, you don't need theelse anymore :)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

😆

private$memoryResolver;

publicfunction__construct(
ReceiverInterface$decoratedReceiver,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Also, we don’t use multi-line constructors in Symfony

@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch 2 times, most recently from0a8460d to37ee3a2CompareApril 20, 2018 13:11
sroze
sroze previously approved these changesApr 20, 2018
@sroze
Copy link
Contributor

The tests are failing. Looks like some infinite loop because the tests for the component just never ends. Can you look at it? Also, I believe we should use inject thelogger within the decorators now that it's possible: inject it to the command and to the receivers.

@sdelicata
Copy link
ContributorAuthor

I've reproduced it. I'll try to fix soon

@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch fromf836b55 toa4f1205CompareApril 20, 2018 19:23
@sdelicata
Copy link
ContributorAuthor

Test fixed.
MaximumCounterReceiver doesn't increase its internal counter anymore when receiving null message, so it will never stop :p

@sdelicata
Copy link
ContributorAuthor

Also, I believe we should use inject the logger within the decorators now that it's possible: inject it to the command and to the receivers
@sroze That's exactly what I planed ;)

@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch from0babb6d tob13adcbCompareApril 20, 2018 20:31
$receiver->receive(function ($message)use ($receiver, &$receivedMessages) {
$this->assertNull($message);

if (2 == ++$receivedMessages) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

strict comparison=== ?

sroze reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

$size =$matches[1] *1024 *1024 *1024;
}elseif ('M' ==$matches[2]) {
$size =$matches[1] *1024 *1024;
}elseif ('K' ==$matches[2]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

same here and above.

sroze reacted with thumbs up emoji
$handler($message);

$memoryResolver =$this->memoryResolver;
if ($memoryResolver() >=$this->memoryLimit) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

the limit is described as

Use the --memory-limit option to stop the worker if it exceeds a given memory usage limit

"exceed" means more than the limit, so>, not>=

sroze and sdelicata reacted with thumbs up emoji
/**
* @dataProvider memoryProvider
*/
publicfunctiontestReceiverStopsWhenMemoryLimitExceeded($memoryUsage,$memoryLimit,$shouldStop)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

please add type declarations

yethee and sdelicata reacted with confused emoji
@srozesroze dismissed theirstale reviewApril 21, 2018 14:29

Changes to be made

@sroze
Copy link
Contributor

Status: Needs work

@ostrolucky
Copy link
Contributor

I don't like naming of these. IMO it should signify what's being done when limit is exceeded. Otherwise, there will be confusion when somebody implements receiver with same trigger but another action. Also, I had no idea what it does until I looked into code. I thought it will just wait until memory is freed up or it will try to release some memory.

MaximumCountReceiver -> AbortWhenMaximumCountIsExceededReceiver
MemoryLimitReceiver -> AbortWhenMaximumMemoryIsExceededReceiver

@sroze
Copy link
Contributor

That's a fair point you have here@ostrolucky. Though, no need to "maximum" if we already have "exceeded". Also, the receivers have this notion of "stop", so I'd suggest:

  • MaximumCountReceiver ->StopWhenMessageCountIsExceededReceiver
  • MemoryLimitReceiver ->StopWhenMemoryUsageIsExceededReceiver
ostrolucky and sdelicata reacted with thumbs up emoji

$this->decoratedReceiver->stop();
}

privatefunctionconvertToOctets(string$size):int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I fully agree.

$this->decoratedReceiver->stop();
}

privatefunctionconvertToOctets(string$size):int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Implementation should be copied from existing code where we already have such logic in different components (seeSymfony\Component\HttpKernel\DataCollector\MemoryDataCollector::convertToBytes for instance).

sdelicata reacted with thumbs up emoji
@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch 2 times, most recently from6826842 tof8e8125CompareApril 22, 2018 17:53
$receiver->receive(function ($message)use ($receiver, &$receivedMessages) {
$this->assertNull($message);

if (2 == ++$receivedMessages) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

$logger =$this->createMock(LoggerInterface::class);
$logger->expects($this->once())->method('info')
->with(
$this->equalTo('Receiver stopped due to memory limit of {limit} exceeded'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

As FYI, you don't need$this->equalTo. This would work:

->with('Receiver stopped due to memory limit of {limit} exceeded',array('limit' =>64 *1024 *1024));

$this->decoratedReceiver =$decoratedReceiver;
$this->memoryLimit =$memoryLimit;
$this->logger =$logger;
$this->memoryResolver =$memoryResolver ?:function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

??

sroze, yceruto, and ostrolucky reacted with thumbs down emoji

publicfunctionreceive(callable$handler):void
{
$callable =$this->callable;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

($this->callable)($handler);

@sroze
Copy link
Contributor

@fabpot could you update your review please?


privatefunctionconvertToBytes($memoryLimit)
{
if ('-1' ===$memoryLimit) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I really don't get the point of this-1 here. I appreciate it's coming from a copy/pasted code somewhere else but I'd remove it.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I agree

@Tobion
Copy link
Contributor

@sdelicata please squash your commits into a single commit. some commit seems to be authored with a different email, so we cannot squash them.

$worker->run();
}

privatefunctionconvertToBytes($memoryLimit)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

missing types

@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch frome733ea7 to7fe7738CompareApril 26, 2018 08:28
@sdelicatasdelicataforce-pushed thefeat_memory_limit_consumer branch from7fe7738 to08f98cfCompareApril 26, 2018 08:29
@sdelicata
Copy link
ContributorAuthor

@Tobion Squash done

@Tobion
Copy link
Contributor

Thanks for your work on this new feature!

@TobionTobion merged commit08f98cf intosymfony:masterApr 26, 2018
Tobion added a commit that referenced this pull requestApr 26, 2018
…agesCommand` (sdelicata)This PR was merged into the 4.1-dev branch.Discussion----------[Messenger] Add a memory limit option for `ConsumeMessagesCommand`| Q             | A| ------------- | ---| Branch?       | master for features| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | no| Tests pass?   | yes| License       | MITNew feature to add a memory limit option to the ConsumeMessagesCommand.```bin/console messenger:consume-messages <receiver-name> -m 128```Commits-------08f98cf [Messenger] Add a memory limit option for `ConsumeMessagesCommand`
@fabpotfabpot mentioned this pull requestMay 7, 2018
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@ycerutoycerutoyceruto left review comments

@fabpotfabpotfabpot requested changes

+5 more reviewers

@ostroluckyostroluckyostrolucky left review comments

@TobionTobionTobion approved these changes

@srozesrozesroze approved these changes

@ro0NLro0NLro0NL left review comments

@linaorilinaorilinaori left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.1

Development

Successfully merging this pull request may close these issues.

10 participants

@sdelicata@sroze@ostrolucky@Tobion@fabpot@ro0NL@linaori@yceruto@nicolas-grekas@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp