Skip to content

Bug in PubSub client health check handling #3791

@ManelCoutinhoSensei

Description

@ManelCoutinhoSensei

Hi, I think there might be an inconsistency (or bug) in the PubSub client related to how health check responses are handled.

In my application, I encountered the following error:

File "/usr/local/lib/python3.12/dist-packages/redis/client.py", line 1016, in punsubscribe
    return self.execute_command("PUNSUBSCRIBE", *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/redis/client.py", line 874, in execute_command
    self.clean_health_check_responses()
  File "/usr/local/lib/python3.12/dist-packages/redis/client.py", line 890, in clean_health_check_responses
    raise PubSubError(
redis.exceptions.PubSubError: A non health check response was cleaned by execute_command: redis-py-health-check

After reading through the code, I noticed that while is_health_check_response allows for receiving either a list of ["pong", "redis-py-health-check"] or only "redis-py-health-check", this behavior seems inconsistent between the decode_responses=True and decode_responses=False cases:

redis-py/redis/client.py

Lines 826 to 830 in 028245c

self.health_check_response_b = self.encoder.encode(self.HEALTH_CHECK_MESSAGE)
if self.encoder.decode_responses:
self.health_check_response = ["pong", self.HEALTH_CHECK_MESSAGE]
else:
self.health_check_response = [b"pong", self.health_check_response_b]

This inconsistency means that the check here:

redis-py/redis/client.py

Lines 1004 to 1007 in 028245c

return response in [
self.health_check_response, # If there was a subscription
self.health_check_response_b, # If there wasn't
]

Can yield:

  • With decode_responses=False:
[[b"pong", b"redis-py-health-check"], b"redis-py-health-check"]
  • With decode_responses=True:
[["pong", "redis-py-health-check"], b"redis-py-health-check"]

Instead of the expected:

[["pong", "redis-py-health-check"], "redis-py-health-check"]

I might be mistaken, and the issue could originate elsewhere, but this seems like a possible source of the inconsistency.

Environment:

  • redis-py version: 6.4.0
  • Python version: 3.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions