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

When using AsyncIOScheduler in version 3.11, decorators cannot be used. #1003

Closed
3 tasks done
SaucePlum opened this issue Dec 19, 2024 · 12 comments
Closed
3 tasks done
Labels

Comments

@SaucePlum
Copy link

Things to check first

  • I have checked that my issue does not already have a solution in the FAQ

  • I have searched the existing issues and didn't find my bug already reported there

  • I have checked that my bug is still present in the latest release

Version

3.11

What happened?

When using AsyncIOScheduler in version 3.11, decorators cannot be used.
error message:runtimeerror event loop is closed

b2bcb272e8a89401d1c1e9b3410fa30

How can we reproduce the bug?

file1.py
b2bcb272e8a89401d1c1e9b3410fa30
file2.py
image

@SaucePlum SaucePlum added the bug label Dec 19, 2024
@agronholm
Copy link
Owner

Please provide a minimal working example that demonstrates the issue. I'm not going to type the code from a screenshot.

@SaucePlum
Copy link
Author

Please provide a minimal working example that demonstrates the issue. I'm not going to type the code from a screenshot.

I don't think changing get_event_loop to get_running_loop can fix the problem that AsyncIOScheduler inadvertently creates an invalid event loop when starting up, which makes the scheduler not work at all.

@agronholm
Copy link
Owner

That change makes sure the scheduler does not create an event loop, period. Again, please provide a minimal working example so I can look at the issue.

@SaucePlum
Copy link
Author

SaucePlum commented Dec 19, 2024

That change makes sure the scheduler does not create an event loop, period. Again, please provide a minimal working example so I can look at the issue.

# -*- coding: utf-8 -*-
import asyncio

from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()
async def start_scheduler():
    print(111)
    scheduler.start()

asyncio.run(start_scheduler())


@scheduler.scheduled_job(
    "cron",
    hour=1,
    minute=30,
    id="group_vip_equity",
    next_run_time = "2024-12-19 17:10:00"
)
async def test():
    print("test")
while True:
    pass

@agronholm
Copy link
Owner

You're trying to add a job after you've closed the event loop. The asyncio scheduler can't work without a running event loop.

@SaucePlum
Copy link
Author

That change makes sure the scheduler does not create an event loop, period. Again, please provide a minimal working example so I can look at the issue.

This change actually has a change to the interface, which belongs to breaking chang, which will cause an error in the schedule_job decorator that took effect in the past.

@agronholm
Copy link
Owner

Your example doesn't even work on the previous release.

@SaucePlum
Copy link
Author

Your example doesn't even work on the previous release.

# -*- coding: utf-8 -*-
import asyncio

from apscheduler.schedulers.asyncio import AsyncIOScheduler

# 启动调度任务
scheduler = AsyncIOScheduler()

async def start_scheduler():
    scheduler.start()



@scheduler.scheduled_job(
    "cron", hour=1, minute=30, id="test", next_run_time="2024-12-19 18:07:00"
)
async def test():
    print("test")


asyncio.run(start_scheduler())


while True:
    pass


The above example cannot be scheduled either.

@agronholm
Copy link
Owner

Even though you get no error from this on 3.10.4, it doesn't actually run either, for the reason I mentioned above. You need a running event loop in order to make the scheduler actually work. This is the reason I made this change: to explicitly fail when you're using the scheduler wrong.

@agronholm
Copy link
Owner

The following example works as expected:

import asyncio

from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()


@scheduler.scheduled_job("cron", second="*")
async def test():
    print("test")


async def main():
    scheduler.start()
    await asyncio.sleep(float("inf"))

asyncio.run(main())

@SaucePlum
Copy link
Author

The following example works as expected:

import asyncio

from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()


@scheduler.scheduled_job("cron", second="*")
async def test():
    print("test")


async def main():
    scheduler.start()
    await asyncio.sleep(float("inf"))

asyncio.run(main())

Thanks for the help, I should use asyncio.get_event_loop().create_task (...) to run

@agronholm
Copy link
Owner

The following example works as expected:

import asyncio

from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()


@scheduler.scheduled_job("cron", second="*")
async def test():
    print("test")


async def main():
    scheduler.start()
    await asyncio.sleep(float("inf"))

asyncio.run(main())

Thanks for the help, I should use asyncio.get_event_loop().create_task (...) to run

No, you shouldn't. asyncio.get_event_loop() is deprecated and will be removed in a future Python release. Use asyncio.run() instead.

@agronholm agronholm closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants