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

Tried to handle an error where no error existed #1195

Open
Avivsalem opened this issue Mar 7, 2019 · 13 comments
Open

Tried to handle an error where no error existed #1195

Avivsalem opened this issue Mar 7, 2019 · 13 comments
Assignees

Comments

@Avivsalem
Copy link

hi. we're using pika 0.13.0.
we get the 'Tried to handle an error where no error existed' error log while consuming messages...
the reason i open this issue, is that we studied it a little bit.
first of all, looking at 0.13.0 code, we see that
this line

LOGGER.error('Error event %r, %r', events, error)
gets called (with error=None), and then it leads to this line:
LOGGER.critical("Tried to handle an error where no error existed")

the event we get is 25 (8 bit is on, so it's an error). but the error log is written because 'error' is None.

the culprit, is this line:

handler(fileno, events)
, that calles the handle_error function, with no 'error' param, making it the default None...

the weird part, is the way we encountered it.
we're using the blocking_connection.consume() generator. for some older reason, we passed inactivity_timeout=0.01, which worked fine...
when we changed it to inactivity_timeout=0.0, the error log started to appear. (and when we changed it back, it disappeared again...)

i thought you might want to look at it. although, i noticed that at the master branch, the lines i mentioned above, are not existent. is there a release coming soon with the new code?

thanks!

@lukebakken lukebakken added this to the 0.13.1 milestone Mar 7, 2019
@lukebakken
Copy link
Member

Thanks for the report @Avivsalem . Calling inactivity_timeout=0.0 is allowed but doesn't really make sense. I'll either disallow it or figure out why this error happens.

i noticed that at the master branch, the lines i mentioned above, are not existent. is there a release coming soon with the new code?

Please give 1.0.0b2 a try in your environment. The 1.0.0 release will happen once I get more feedback about the beta release. I don't expect there to be any more API changes for 1.0.0 so you won't be wasting time by changing your code to accomodate them. All of the code in the examples/ directory has already been updated for master.

NOTE: the 1.0.0 release has API changes that are detailed here,

@lukebakken
Copy link
Member

@Avivsalem I also suggest joining the pika-python mailing list if you haven't already. Thanks!

@lukebakken lukebakken self-assigned this Mar 7, 2019
@lukebakken
Copy link
Member

lukebakken commented Mar 7, 2019

I can't reproduce this using Python 3.7.2 or 2.7.15 using 0.13.0b1 and inactivity_timeout=0.0 (code).

If you can think of what might be different in your environment, I'd appreciate it. Thanks! I will re-open this issue if new information allows me to reproduce it.

@Avivsalem
Copy link
Author

We're using 0.13.0 release from pypi (don't know the difference between that and 0.13.0b1)
Second, it happens sporadically on our most heavy consumers.

We use prefetch_count=1
and we consume from mirrored queues if that matters...
Also, we have multiple consumer channels on same connection

@Avivsalem
Copy link
Author

And by multiple consumers, I mean in a one thread round Robin fashion... I'll try to post a gist later...

@Avivsalem
Copy link
Author

Avivsalem commented Mar 8, 2019

@lukebakken
Still didn't manage to pull the code for a gist... But I have some thought about what might be happening...

If you set the heartbeat for a short enough time, and then run the code you wrote on an EMPTY queue, with inactivity_timeout=0.0, eventually, the error will occur (after heartbeat.)
I think it's because when inactivity_timeout=0, the code doesn't process the heartbeats at all... Makes sense?

@Avivsalem
Copy link
Author

@lukebakken
followed it more into the code...
the lines in questions are:

self.connection.process_data_events(time_limit=delta)
is called with time_limit=0
then
self._flush_output(timer.is_ready, common_terminator)
is called, with a _IoloopTimerContext that has 0 as time_limit,
and finally this
while not is_done():
doesn't enter the while loop at all... so

 self._impl.ioloop.poll()
 self._impl.ioloop.process_timeouts()

never gets called...

i believe this is the main difference between 0.0 and 0.01... and the reason for the metioned error... (this, combined with the fact that the heartbeat interval has passed, and was not handled on an empty queue).

i know this is a "voodo" scenario, but we actually encounter this.

@lukebakken
Copy link
Member

Wow, thank you for the detailed analysis! I'll check it out today. Have a great weekend!

@lukebakken lukebakken reopened this Mar 8, 2019
@Avivsalem
Copy link
Author

You too! Thanks for your time.

@lukebakken lukebakken modified the milestones: 0.13.1, 1.0.0 Mar 12, 2019
@lukebakken
Copy link
Member

lukebakken commented Mar 12, 2019

@Avivsalem what heartbeat timeout settings have you tried to reproduce this issue?

@vitaly-krugl - if you have a few minutes to look at this I would appreciate it. It looks as though when inactivity_timeout=0.0 is used, this code won't ever get called, and if a queue is empty heartbeats may not be sent to RabbitMQ because of that.

@Avivsalem
Copy link
Author

We use heartbeat=300

@lukebakken
Copy link
Member

Well, I still haven't been able to reproduce this yet using the default heartbeat value or 300. Since there is a workaround (don't use 0 for inactivity_timeout) I am going to remove this from the 1.0.0 milestone.

@lukebakken lukebakken removed this from the 1.0.0 milestone Mar 27, 2019
@vitaly-krugl
Copy link
Member

vitaly-krugl commented Mar 27, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants