Open spumer opened 1 year ago
@spumer the greenletio run
command is intended to be used with sync applications. You are using it to start Uvicorn, which is not an intended use case.
I think this error independent of application type. Because ThreadPoolExecutor can't be imported
Maybe, yes, that is possible. When you use greenletio run
many of the Python standard classes are replaced with alternative implementations, which are not identical. The ThreadPoolExecutor
class is not currently patched and it accesses private attributes of the Lock
class which exist in the original implementation but not in the green version.
At this time only a short list of modules are patched, several more need to be reviewed and patched. Until then, some things are expected to fail.
Mmm, i will try to implement this protected method.
Looks like we just need recreate internal asyncio.Lock
in this case
First of all, this package implements the regular Lock
class, from threading
. The asyncio.Lock
class does not benefit from this package at all. The lock in question is here.
Second, it is not a primary goal of this library to provide compatibility with private attributes. The idea is to provide compatibility for public attributes and methods. Code that makes assumptions about the internals of other classes is not expected to work. It may not be possible to implement the same private attributes at all, due to the big difference in concurrency models. To address these usages between different modules of the Python standard library, it may be necessary to also patch the module that fails.
Ok, i understand. You are right
Can we convert this discussion to support concurrent.futures.ThreadPoolExecutor
or open the new one and close this?
There are many parts of the standard library that need to be implemented. In fact, only a small portion is available right now. So yes, the thread pool executor should eventually work. But as I said in the beginning of this thread, what you are doing is wrong. Running uvicorn under a patched library makes no sense and is unlikely to ever be supported.
I'm search the way to run sync handlers in fastapi(Fastapi allow write async and sync handlers) through gevent instead real threads (default fastapi behaviour for sync handler) and make app fully async.
Also i want to check how performance changed under load testing this setup.
The monkey patching feature of this package is not really the way to do what you want. The first step is probably to add the @async_
decorator to your handlers, so that FastAPI runs them as async functions. The @async_
decorator will do all the greenlet magic to prevent the loop from blocking. At least in theory, I haven't tested this with FastAPI.
Yes, but i still need monkey patching to work decorated functions correctly. And this is why i run uvicorn, and this is why this issue created :)
@spumer We are going in circles here. The monkey patching is not intended to be used with async applications such as uvicorn or FastAPI, as I indicated above. Monkey patching is for sync applications.
If you have sync code that runs as part of your uvicorn/fastapi app that needs to use greenletio's functions, then you can import them directly from the greenletio.green
packages, or else you can use the patch_blocking context manager to perform a controlled monkey patching that is local to your sync functions, without affecting the overall async environment.
If you are intending to use this package to somehow alter how FastAPI deals with sync functions, then I'm afraid that is not an intended goal. You may be able to make FastAPI think you sync functions are async with the @async_
decorator, but that is the extent of it. I have no plans to make this an extension to FastAPI.
❯ python -V Python 3.11.4 ❯ greenletio run.py web
Output
``` File "run.py", line 7, in