pika: pika throws ChannelWrongStateError('Channel is closed.') on publish
pika version: 1.1.0
As a result of interface link flapping a socket underneath pika’s connection to RabbitMQ became dead. Since this state transition has not been properly processed by client code any subsequent publish() to pika’s Channel then caused this:
File "/opt/venv/lib/python3.6/site-packages/pika/adapters/blocking_connection.py", line 2210, in basic_publish
mandatory=mandatory)
File "/opt/venv/lib/python3.6/site-packages/pika/channel.py", line 421, in basic_publish
self._raise_if_not_open()
File "/opt/venv/lib/python3.6/site-packages/pika/channel.py", line 1389, in _raise_if_not_open
raise exceptions.ChannelWrongStateError('Channel is closed.')
pika.exceptions.ChannelWrongStateError: Channel is closed.
As a result: a code like
try:
self.channel.basic_publish(*a, **k)
except (exceptions.ConnectionClosed, exceptions.ChannelClosed) as error:
log.debug('Try to reconnect in 5 seconds')
time.sleep(5)
self.reconnect()
would fail.
This behaviour was implemented at https://github.com/pika/pika/commit/761ef5cf8e484fe8d52909e767ceef69afc82d3a
But I disagree in total with the approach since it brakes the whole typed exception support of python itself. Typed exceptions are supported for the user of code can just quickly match the error yielded by runtime despite what’s the actual reason. The commit mentioned brakes this and offers code users to revert to strings patterns matching. Instead of raising the same exception in cases:
- channel is in
openingstate but is not ready to operate - channel is [already] closed
one should provide a special type of an exception for each of the cases if the error recovery is supposed to differ, IMO.
For these two cases error recovery approaches obviously to me differ in total. For the channel in opening state it’s wait a little then try again (but don’t reconnect since there’s no reason for it); for the channel is in closed state it could be recover via reconnect. Right now the code user differs what approach to use only with the Exception.args parsing.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Comments: 16 (7 by maintainers)
Commits related to this issue
- Add is_opening method Bump versions for win32 testing Fixes #1240 — committed to pika/pika by lukebakken 2 years ago
- Add is_opening method Bump versions for win32 testing Fixes #1240 — committed to pika/pika by lukebakken 2 years ago
- Merge branch 'main' into gh-1240 — committed to pika/pika by lukebakken 2 years ago
- Merge branch 'main' into gh-1240 — committed to pika/pika by lukebakken 2 years ago
- Merge pull request #1361 from pika/gh-1240 Add is_opening method — committed to pika/pika by lukebakken 2 years ago
Is there any update here? In the connection pool with a heartbeat, connections are getting dropped as well.
@lukebakken hello … this the lgs i got from RabbitMQ . is it ok or i miss some things?
there was no network issue. and after few tries rabbitmq works fine like and then it again gives me channel closed or pika.exceptions.StreamLostError: Stream connection lost: ConnectionResetError(104, ‘Connection reset by peer’)
Hi, I had the same error, but not the exact situation. First I had
basic_publishthat didn’t handle aStreamLostError. Then, on the same channel anotherbasic_publishraised aChannelWrongStateErrorwith the same message.I think it’s confusing, since that the documentation says it will raise
UnroutableErrorandNackErroronly.