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

queue_declare silently returning null on timeout #1101

Open
ascheja opened this issue Jul 5, 2023 · 3 comments
Open

queue_declare silently returning null on timeout #1101

ascheja opened this issue Jul 5, 2023 · 3 comments
Assignees
Labels

Comments

@ascheja
Copy link

ascheja commented Jul 5, 2023

Version(s) affected: 3.5.2 (probably all)

Description
AMQPChannel::declare_queue() returns null ($no_wait flag is set to false) in case the read for the response timed out.

How to reproduce
Don't really have a reproducer here, we have a lot of php processes running and currently have trouble with some timeouts (cause tbd) and also some errors because we expect an array with the queue name to be returned from queue_declare, but we don't get the array built by queue_declare_ok but null instead.

I've been digging through the code and the only way I see how AbstractChannel::wait() could return null is by either the dispatched method returning null (but queue_declare_ok never returns null) or if there is a break in the while (true) thus ending the method, so the void return is converted to null on assignment.

There are two cases where break is used inside the loop:

  • if $non_blocking is set to true -> not possible as queue_declare always calls wait() with $non_blocking = false
  • In case of a AMQPNoDataException

Possible Solution
As only the AMQPNoDataException remains, considering the comment in the catch-block, for blocking calls the exception should IMO be rethrown instead of just breaking out of the loop and thus "returning" null, or the loop should just continue.

As a side note - I guess it makes sense to append an explicit return null; at the end of the wait() method? I personally find methods returning either void or mixed rather sketchy...

Additional context

  • We're using the stream connection type
  • Connect timeout is set to 10 seconds
  • Read/Write timeout is set to 10 seconds
  • Channel RPC timeout is not set -> defaults to 0?
@ramunasd ramunasd self-assigned this Jul 5, 2023
@ramunasd ramunasd added the bug label Jul 5, 2023
@ramunasd
Copy link
Member

ramunasd commented Jul 5, 2023

Thanks for reporting!

I guess it's because to You have default value for channel RPC timeout. 0 is special case when waiting for network frames. It is being converted to null timeout when executing stream_select, which means ".. can block indefinitely, returning only when an event on one of the watched streams occurs (or if a signal interrupts the system call). " [1]

It's really hard to tell why stream_select did not wait until frame. Perhaps something happened with connection. In general, we cannot determine what exactly happened in TCP layer and act accordingly.

Anyways, I don't think You want to block your code indefinitely :) It would be good practice to use appropriate timeouts.

We will change default values in next major version, once we start work on it.

BTW, You forgot to mention PHP version.

[1] https://www.php.net/manual/en/function.stream-select.php

@ascheja
Copy link
Author

ascheja commented Jul 5, 2023

Thanks for the quick response.

We're still on php 7.4.33.

I'll try specifying the channel RPC timeout and get back to you tomorrow.

@ascheja
Copy link
Author

ascheja commented Jul 6, 2023

Seems like setting the channel RPC timeout to a non-zero value was the right call, this problem is gone now.

Thanks for the help!

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

No branches or pull requests

2 participants