Closed belingud closed 2 years ago
Hi @belingud
Thanks for submitting this well-thought out issue. Using grequests
together with other applications, particularly ones that also use gevent
is often a source of pain when using this project. In general, we don't recommend using grequests
together with such other packages and we recommend use of grequests
be, more or less, standalone.
Nevertheless, such use cases seem to arise commonly.
There's a few things the stand between the current situation and a, perhaps, more desirable state. There's maybe also some alternative ways that grequests
can use monkey patching to make things easier for other applications.
One suggestion has been to make the monkey patching in grequests less aggressive. I'm not sure, however, which components need to be patched by grequests. But if we could limit the patching to exactly what grequests needs, that may make it more compatible with other applications.
SInce the patch happens on import, I'm not sure what the best way would be to give users control of the monkey patch would be. I'll think some more on this. But at the end of the day, grequests does need certain things patched and may not even work correctly without those patches, which may mean that, ultimately, grequests is inherently incompatible with certain applications.
In the meantime, @belingud it is perhaps useful to know that grequests is composed of just a single file. You could try copying grequests directly to your own project (instead of installing it via pip) and modify the monkeypatching to see what may work for you! It will be useful to know, for example, whether grequests works without patching thread
If you want to disable gevent.monkey.patch_all()
in grequests
(without forking), this should work:
import mock # unittest.mock in Python 3.3+
with mock.patch('gevent.monkey.patch_all', lambda *args, **kwargs: None):
import grequests
It is best if gevent.monkey.patch_all()
is only done in application entrypoints, not libraries, because it should be done before all other imports, and should only be done once. From the gevent documentation:
Patching should be done as early as possible in the lifecycle of the program. For example, the main module (the one that tests against main or is otherwise the first imported) should begin with this code, ideally before any other imports
Even if you can't control where import grequests
is done, doing the above mock.patch()
in your application entrypoint should work, because Python should only import grequests
once. Once it is imported that version keeps getting used, and import-time side effects of grequests
shouldn't get run again.
Hi, there~
This is a really useful project, and I have fun with that. And also I am facing a problem using this project with my flask server in product environment, this is my problem.
I am using
gunicorn
withgevent
to deploy my flask server, and you knowgunicorn
have already executedmonkey.patch_all()
, whengrequests
load, it would cause following warning.Although I can use this lib in my flask server any way, but I am considering a situation that if I am developing a
gevent
support project and already patched without threading, just likemonkey.patch_all(thread=False)
, i would facing a problem that i can not running my project correctly.Like the warning said, double patch would cause all True parameters patched, and I could not pass a False value to thread, this is what I dont want it happen.
So, I sincerely suggest that it would be really good improvement for customization to give out the control of
monkey patch
to user. And also, other project not only flask web server, like some projects using gevent and already have a stable way to patch their projects, could use this lib in a very friendly way.