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
AsyncioExecutor not truly async #96
Comments
Original comment by Alex Grönholm (Bitbucket: agronholm, GitHub: agronholm): It has occurred to me to offer an executor that runs the jobs in the event loop thread. But by default I wanted to offer an interface that always executed jobs in a thread regardless of the scheduler type (GeventScheduler being the obvious exception). I can't change this without breaking the API, which means not before 4.0. But I could add a suitable executor in 3.1. The same will have to be done with the Tornado and Twisted schedulers though. |
Original comment by Bernard Kerckenaere (Bitbucket: bernieke, GitHub: bernieke): disclaimer: I'm on Python 3.5.0 For some reason the yield from in the modified run_job throws an "TypeError: 'NoneType' object is not iterable" exception for me. All I actually needed to get it to work for me was:
So instead of using a modified run_job, I just wrapped the existing run_job in a coroutine. |
Original comment by Bernard Kerckenaere (Bitbucket: bernieke, GitHub: bernieke): I just figured out why I didn't need the yield from in my use case. The function I'm calling isn't a coroutine itself, but schedules one by calling asyncio.async. So I guess the proper solution would be to have run_job check if job.func is a coroutine, and yield from if it is. That way both use cases should work. |
in your example asyncio_.py i try declare function
, although, no error was raised, but it not done. How i work with AsyncioScheduler? |
Scheduling of coroutine functions is marked to be implemented in the 3.3 milestone. Meanwhile, you can use the event loop's |
Plzzz, illustrate example how to use |
@agronholm Does it have any blocking issues that should be taken care of? |
This particular thing doesn't. However, the next step is to get 3.2.0 out which will fix the use case 3.1.0 broke -- adjusting jobs in job stores before the scheduler starts processing the jobs. The code is done, the tests are just unfinished. I expect to make a release this weekend. The biggest problem with async execution is that I have to duplicate pretty much all of run_job() for use with scheduled coroutines and I don't want to do that. So I'm still looking for elegant solutions to that. |
@TechBK I am now using asyncio executor as the following. being execute() the function used on add_job()
@agronholm I don't see what you mean. AFA I see, you would just need run a check on the job func and if it's a coroutine, and await from it if so, no? |
How would that work with Python 2? |
Following this? Other option is to define execute_job() as a function where just the execution of the job is handled, and still have run_job() globally defined, leaving room to each executor implement it's own. That way, you could reimplement execute_job() in each Executor, making sure that it does what it says (the actual function, is executed in a thread, in a coroutine, in an eventlet, etc.) The good part of this one is that you wouldn't run into any problems importing asyncio in the AsyncIOExecutor. You would need to move any logic you may have already created to overcome these limitations for other modules (spawning a thread etc.) to the execute_job() function of each executor. |
Ok @txomon , can you show me how to write run_job() in a way that works for both coroutine callables and regular functions in a manner that doesn't duplicate all the code? I've tried and failed. |
@agronholm check #134 |
i am waiting for solution of issue :( |
And you'll remain waiting for a while. The next release will not fix this -- 3.3 at the earliest will. Meanwhile you can try hacks involving |
@txomon i try to run ur code, but when job done, So, i cant repeat job. |
@txomon's code won't work. You can't just add new event loops whenever you feel like it. |
You have to pass the existing event loop to the scheduled callable and then use |
|
I know that. You have to pass it a callable which then calls |
But to enable the runner to properly detect exceptions and such, you need to then have a |
Super thank 👍 |
@agronholm: we are evaluating to re-adopt apscheduler in GlobaLeaks: globaleaks/GlobaLeaks#1769 What i'm failing to understand is if this functionality is functional in twisted since previous version packaged in Debian/Ubuntu, or if its only available now in relation to python 3.5. Is there any way to handle this behaviour with twisted and python 2.7 by using the twisted inlineCallbacks? (thanks) |
There is no way to detect |
i see thank you for the explanation |
The fundamental problem here is that currently all those executors default to running the jobs in worker threads. If I change this default behavior, it will break things for a lot of people. I was able to add native coroutine support because they're detectable and didn't work before anyway so I was able to add code that takes a different code path when a coroutine function is detected. |
understood; sadly we will have still to go for a custom implementation because we will be stuck with python 2.7 for some time and in general we can use eventually use only the apscheduler packaged in ubuntu trusty/xenial. |
You could easily implement a custom executor that runs jobs directly in the reactor thread. In fact, that makes me wonder why I'm not doing that – providing an alternate executor that does this, even if it's not the default one. |
Thinking more about it, I'm not really sure if it's easy but it's far less work than implementing all those monitoring etc. features all by yourselves. |
the basic custom implementation that we use is the following: https://github.com/globaleaks/GlobaLeaks/blob/master/backend/globaleaks/jobs/base.py the main issue is not be able to stop something that maybe can be stuck into the reactor, but this is mostly an issue with twisted that i think is not solvable in any way. |
So is your problem that the reactor could be stuck running code that's blocking everything else and you can't stop it? |
I didn't realize Ubuntu had such an ancient version of APScheduler. Why do you restrict yourselves to OS provided packages? |
Originally reported by: Lennart Bastian (Bitbucket: bastianl, GitHub: bastianl)
I have been using the
AsyncioScheduler
with theAPScheduler
to schedule tasks asynchronously. However, I want to schedule jobs (coroutines) in the same event loop that the scheduler is running in.It looks like the
AsyncioExectutor
is running tasks in a separate thread, and not as coroutines but rather regular functions. In fact, it doesn't seem like you can schedule any kind of asynchronous functions. Is this the intended behavior? What's the point of calling it anasyncio
executor?To solve this I modified the function
run_job
to work asynchronously, and tweaked the executor to run jobs asasyncio.Tasks
which are automatically inserted into the eventloop.See this.
Maybe we can modularize the
run_job
function and split it into two functions, one of which works asynchronously. Let me know what you think, am happy to submit a pull request.The text was updated successfully, but these errors were encountered: