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

Mismatch in outputs of blocking XREAD in Fake vs Real redis libraries #308

Closed
amitgargOfficial opened this issue May 9, 2024 · 1 comment

Comments

@amitgargOfficial
Copy link

amitgargOfficial commented May 9, 2024

I am using pyredis==5.0.3 and fakeredis=2.22.0 in Python3.8.10, and the output of XREAD from the fake library is different from the one of a real Redis client. Specifically, the faker library always returns an empty array when using a blocking call against XREAD, unless count is also set. I have tried using 5.0.7 and 7.2.4 for my redis server, and gotten the same results.

Here is a small demo to reproduce:

import redis
from fakeredis import FakeServer, FakeStrictRedis


def main():
    fake_server = FakeServer()
    fake_client = FakeStrictRedis(server=fake_server)

    k = "key"
    fake_client.xadd(k, {"value": 1234})
    streams = {k: "0"}

    print(f"FAKE XRANGE - {fake_client.xrange(k)}")
    print(f"FAKE BLOCKING XREAD - {fake_client.xread(streams=streams, block=10)}")
    print(f"FAKE NON BLOCKING XREAD - {fake_client.xread(streams=streams)}")
    print(f"FAKE BLOCK COUNT XREAD - {fake_client.xread(streams=streams, block=10, count=10)}")

    real_client = redis.Redis(host='localhost', port=6379, db=1)
    real_client.xadd(k, {"value": 1234})

    print()

    print(f"REAL XRANGE - {real_client.xrange(k)}")
    print(f"REAL BLOCKING XREAD - {real_client.xread(streams=streams, block=10)}")
    print(f"REAL NON BLOCKING XREAD - {real_client.xread(streams=streams)}")
    print(f"REAL BLOCK COUNT XREAD - {real_client.xread(streams=streams, block=10, count=10)}")

    real_client.delete(k)


if __name__ == '__main__':
    main()

Which yields the output:

FAKE XRANGE - [(b'1715212536143-0', {b'value': b'1234'})]
FAKE BLOCKING XREAD - []
FAKE NON BLOCKING XREAD - [[b'key', [(b'1715212536143-0', {b'value': b'1234'})]]]
FAKE BLOCK COUNT XREAD - [[b'key', [(b'1715212536143-0', {b'value': b'1234'})]]]

REAL XRANGE - [(b'1715212536166-0', {b'value': b'1234'})]
REAL BLOCKING XREAD - [[b'key', [(b'1715212536166-0', {b'value': b'1234'})]]]
REAL NON BLOCKING XREAD - [[b'key', [(b'1715212536166-0', {b'value': b'1234'})]]]
REAL BLOCK COUNT XREAD - [[b'key', [(b'1715212536166-0', {b'value': b'1234'})]]]

Looking in the code, a None count parameter of the XREAD is preventing the _xread method from returning the relevant items.

    def _xread(...):
            ...
            stream_results = self._xrange(item.value, start_id, max_inf, False, count)
            if first_pass and (count is None):
                return None
            ...

Is this by design, or a bug? If it's by design, could you share more about the reason why this specific behavior is different from the one in real redis?

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@cunla cunla closed this as completed in 3fee210 May 10, 2024
@cunla
Copy link
Owner

cunla commented May 10, 2024

Thanks, fixed it. It will be published in the next release

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

No branches or pull requests

2 participants