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

Error: Event loop is closed when running asyncio + sentinel examples #3431

Open
pedroplytix opened this issue Nov 13, 2024 · 8 comments · May be fixed by #3438
Open

Error: Event loop is closed when running asyncio + sentinel examples #3431

pedroplytix opened this issue Nov 13, 2024 · 8 comments · May be fixed by #3438

Comments

@pedroplytix
Copy link

Version: redis-py: 5.2 / redis 6.2.7

Platform: Python 3.12.7 on Debian (Docker container: python:3.12.7-slim-bookworm)

Description: Running the example provided in redis-py documentation to connect to sentinel using asyncio:

import asyncio
from redis.asyncio.sentinel import Sentinel

async def main():
    sentinel = Sentinel([("localhost", 26379), ("sentinel2", 26379)])
    r = sentinel.master_for("mymaster")

    ok = await r.set("key", "value")
    assert ok
    val = await r.get("key")
    assert val == b"value"


if __name__ == "__main__":
    asyncio.run(main())

I get this error:

Exception ignored in: <function AbstractConnection.__del__ at 0x7f53bc6e14e0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/connection.py", line 215, in __del__
    f"unclosed Connection {self!r}", ResourceWarning, source=self
                          ^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/sentinel.py", line 35, in __repr__
    f"(service={pool.service_name}"
                ^^^^^^^^^^^^^^^^^
ReferenceError: weakly-referenced object no longer exists

If I try to close the connection after assert val == b"value":

...
    assert val == b"value"
    await r.aclose()
...

I get this error:

Exception ignored in: <function AbstractConnection.__del__ at 0x7ff6587ed580>
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/connection.py", line 217, in __del__
    self._close()
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/connection.py", line 224, in _close
    self._writer.close()
  File "/usr/local/lib/python3.12/asyncio/streams.py", line 358, in close
    return self._transport.close()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1210, in close
    super().close()
  File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 875, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "/usr/local/lib/python3.12/asyncio/base_events.py", line 795, in call_soon
    self._check_closed()
  File "/usr/local/lib/python3.12/asyncio/base_events.py", line 541, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Checking with older redis-py versions, I've checked that this code worked fine in redis==5.0.0 and redis==5.0.1, but started to fail in redis==5.0.2

@stg609
Copy link

stg609 commented Nov 14, 2024

I get the same error in redis==5.1.0 , 5.2.0

@rad-pat
Copy link

rad-pat commented Nov 14, 2024

Have you tried also adding await sentinel.aclose() ?

@IlianIliev
Copy link

Ok, I dug a bit into the problem and I kind of managed to reproduce it.
For me, the error is thrown only if the service name does not match the one of the actual sentinel. For example:

    r = sentinel.master_for("mymaster")  # wrong name, causes the event loop closed
    r = sentinel.master_for("redis-py-test")  # correct name, everything works

With that said, please open your redis.conf and check if the name of the service matches the one you are providing. This should solve the issue you are facing.

As for the actual reason to see this error instead of a more informative one, I will have to dig a bit more to see what causes it.

@pedroplytix
Copy link
Author

pedroplytix commented Nov 15, 2024

@IlianIliev it is not my case:

127.0.0.1:26379> sentinel master other
(error) ERR No such master with that name

127.0.0.1:26379> sentinel master mymaster
 1) "name"
 2) "mymaster"

Before I ran the script, I check key key in redis and it is empty:

127.0.0.1:6379> get key
(nil)

After I ran the test:

> python app.py 
Exception ignored in: <function AbstractConnection.__del__ at 0x7f103ca9e980>
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/connection.py", line 215, in __del__
    f"unclosed Connection {self!r}", ResourceWarning, source=self
                          ^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/sentinel.py", line 35, in __repr__
    f"(service={pool.service_name}"
                ^^^^^^^^^^^^^^^^^
ReferenceError: weakly-referenced object no longer exists
Exception ignored in: <function AbstractConnection.__del__ at 0x7f103ca9e980>
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/connection.py", line 217, in __del__
    self._close()
  File "/usr/local/lib/python3.12/site-packages/redis/asyncio/connection.py", line 224, in _close
    self._writer.close()
  File "/usr/local/lib/python3.12/asyncio/streams.py", line 358, in close
    return self._transport.close()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1210, in close
    super().close()
  File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 875, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "/usr/local/lib/python3.12/asyncio/base_events.py", line 795, in call_soon
    self._check_closed()
  File "/usr/local/lib/python3.12/asyncio/base_events.py", line 541, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

If I query redis for key key:

127.0.0.1:6379> get key
"value"

@vladvildanov
Copy link
Collaborator

Thanks for reaching out! Will start an investigation on this

@vladvildanov
Copy link
Collaborator

@pedroplytix You're right, it's started since 5.0.2 because of this PR. It's a part of 5.0.2 release

https://github.com/redis/redis-py/pull/3001/files#diff-9d65b3446d551c0ed9e7bb0a16cf7b31f8b94c1024b9bf05afaa63ce70950019R29

@vladvildanov
Copy link
Collaborator

Looks like up to this point garbage collector already removed an original ConnectionPool object, so it's impossible to reference it

@vladvildanov vladvildanov linked a pull request Nov 18, 2024 that will close this issue
6 tasks
@vladvildanov
Copy link
Collaborator

@pedroplytix Feel free to join the review of #3438 that should fix both if this issues

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

Successfully merging a pull request may close this issue.

5 participants