Thanks to visit codestin.com
Credit goes to github.com

Skip to content

enable heartbeat (by default) for queueconsumer#383

Merged
mattbennett merged 9 commits into
nameko:masterfrom
mattbennett:consumer-heartbeats
Nov 28, 2016
Merged

enable heartbeat (by default) for queueconsumer#383
mattbennett merged 9 commits into
nameko:masterfrom
mattbennett:consumer-heartbeats

Conversation

@mattbennett

Copy link
Copy Markdown
Member

Kombu does actually support consumer heartbeats in more recent versions, if used with py-amqp.

This PR also removes an override that was lifted (in 2013) from Kombu for (I think) reasons of optimisation. The test suite certainly passes without it, so I think it can safely be dropped.

@davidszotten davidszotten left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks like a bunch of failures on travis. :(

Comment thread nameko/messaging.py
def consume(self, limit=None, timeout=None, safety_interval=0.1, **kwargs):
""" Lifted from Kombu.

We switch the order of the `break` and `self.on_iteration()` to

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is this no longer an issue? how long is that timeout and would stopping have to wait for it without this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The default timeout is 0.1 seconds so I don't think there's anything to worry about there. If timeout is never set as per the comment it has no effect anyway.

@kollhof can you remember why you did this?

Comment thread nameko/messaging.py
heartbeat = self.container.config.get(
HEARTBEAT_CONFIG_KEY, DEFAULT_HEARTBEAT
)
self._connection = Connection(self.amqp_uri, heartbeat=heartbeat)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is there any overhead to heartbeats?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There is some extra network traffic but no performance implication as far as I'm aware. Services will probably get faster because broken connections are discovered earlier.

Comment thread nameko/messaging.py

if self._connection is None:
self._connection = Connection(self.amqp_uri)
heartbeat = self.container.config.get(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

are these just ignored with older (or non-forked) amqp?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If this works with our oldest supported kombu then I think we're fine. It's ignored for non-pyamqp transports and has been supported there since 0.9.1.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ignored (as opposed to explodes) is great

@mattbennett

Copy link
Copy Markdown
Member Author

The test suite passed for me locally (OS X, Python 3.4.3) but the failures here do seem to be real. I will investigate.

Comment thread test/test_errors.py
# proxy.task() will hang forever because it generates an error
proxy.task.call_async()

with eventlet.Timeout(1):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this was taking longer than a second?

did we make stuff slower or is this travis having issues?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hard to say. I added a timer context manager around this locally and container.wait only ever took ~0.005 seconds.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

But I also can't get it to fail locally...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hm. looking at travis, builds historically take ~3 minutes. this pr is around 9. worth checking if this is travis having issues or this pr

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Travis is variable. Re-running master now is taking 4-5 mins: https://travis-ci.org/nameko/nameko/builds/177243811

There is some small impact here on tear-down times, but I think it is just 0.1 seconds. It becomes apparent in here because we do it a lot.

Do we really care that services take slightly longer to stop? I could retrofit the call to conn.heartbeat_check() into our lifted method, but I'd rather remove the override. We wouldn't justify adding the override for a small improvement in test-run time.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should we add these back? (make the failure case a timeout instead of a hung test)

i guess they also helped us catch the performance issue

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think we should put them back. We use pytest-timeout to catch hanging tests now, which is what these were originally used for.

Tracking the average test execution time would be a much better way to spot performance issues. It probably wouldn't be too difficult to send stats to a free tier on something like https://plot.ly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ah, forgot about pytest-timeout. though i can't see where we switch it on..

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ha, I thought it defaulted to a 30 second timeout if installed. But apparently not. I'll add it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sounds a bit long for an individual test but we can tweak later

@mattbennett

Copy link
Copy Markdown
Member Author

On reflection I think the best resolution for now is to restore the consume override which processes on_iteration before breaking the loop. It's unfortunate that it requires an overridde, but when the QueueConsumer is stopping, switching the order is not a material change.

I have changed the safety_interval timeout back to the kombu default though, because I think it has the potential to introduce strange networking behaviour.

I'd like to land this PR as it is so we get a) "default" timeout parameters and b) consumer heartbeats. We can assess whether there's a better way to use the ConsumerMixin (or replace it altogether) separately later.

Comment thread nameko/messaging.py Outdated

return self._connection

def consume(self, limit=None, timeout=None, safety_interval=1, **kwargs):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

did you move this intentionally? makes the diff harder to see

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sorry, not intentional. Have moved it back again

@davidszotten

Copy link
Copy Markdown
Member

i guess once the toxiproxy lands we can add integration tests for the heartbeat

@davidszotten

Copy link
Copy Markdown
Member

👍

needs changelog

@mattbennett mattbennett merged commit 8721c88 into nameko:master Nov 28, 2016
@mattbennett mattbennett deleted the consumer-heartbeats branch November 28, 2016 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants