agronholm / apscheduler

Task scheduling library for Python
MIT License
6.3k stars 712 forks source link

Event loop is closed when using AsyncScheduler with RedisEventBroker #937

Closed de-shev closed 3 months ago

de-shev commented 4 months ago

Things to check first

Version

4.0.0a5

What happened?

I'm encountering a RuntimeError: Event loop is closed when using AsyncScheduler with RedisEventBroker.

import asyncio
import logging
from datetime import datetime

from apscheduler import AsyncScheduler
from apscheduler.eventbrokers.redis import RedisEventBroker
from apscheduler.triggers.interval import IntervalTrigger
from redis.asyncio.client import Redis

from config import settings

def tick():
    print("Hello, the time is", datetime.now())

async def main():
    redis_url = f"redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}"
    event_broker = RedisEventBroker(client_or_url=Redis.from_url(redis_url))

    async with AsyncScheduler(event_broker=event_broker) as scheduler:
        await scheduler.add_schedule(tick, IntervalTrigger(seconds=1), id="tick")

logging.basicConfig(level=logging.INFO)
asyncio.run(main())

Error:

INFO:apscheduler._schedulers.async_:Added new schedule (task='__main__:tick', trigger=IntervalTrigger(seconds=1, start_time='2024-07-11 23:08:37.256226+07:00')); next run time at 2024-07-11 23:08:37.256226+07:00
Exception ignored in: <function StreamWriter.__del__ at 0x7f59ab40b060>
Traceback (most recent call last):
  File "/home/de_shev/.pyenv/versions/3.11.6/lib/python3.11/asyncio/streams.py", line 395, in __del__
    self.close()
  File "/home/de_shev/.pyenv/versions/3.11.6/lib/python3.11/asyncio/streams.py", line 343, in close
    return self._transport.close()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/de_shev/.pyenv/versions/3.11.6/lib/python3.11/asyncio/selector_events.py", line 860, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "/home/de_shev/.pyenv/versions/3.11.6/lib/python3.11/asyncio/base_events.py", line 761, in call_soon
    self._check_closed()
  File "/home/de_shev/.pyenv/versions/3.11.6/lib/python3.11/asyncio/base_events.py", line 519, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

And if I don't use the Redis object explicitly, but only the URL:

async def main():
    redis_url = f"redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}"
    event_broker = RedisEventBroker(client_or_url=redis_url)

    async with AsyncScheduler(event_broker=event_broker) as scheduler:
        await scheduler.add_schedule(tick, IntervalTrigger(seconds=1), id="tick")

I get the following error:

AttributeError: 'Redis' object has no attribute 'aclose'. Did you mean: 'close'?
Exception ignored in: <function StreamWriter.__del__ at 0x7f54aa40b060>

And by the way, is it possible to use the synchronous Scheduler with RedisEventBroker?

How can we reproduce the bug?

Run the provided script

agronholm commented 4 months ago

Are you sure you're running a recent version of the redis library? There certainly is an aclose() method.

agronholm commented 3 months ago

Closing due to lack of responses. Presumably the issue was resolved by upgrading redis.