Por que gevent em um aplicativo Flask com Apache + mod_wsgi está gerando NotImplementedError?
Pergunta
Estou tendo um problema implantando meu aplicativo Flask com Apache (MOD_WSGI) e Gevent em uma hospedagem compartilhada (Webfaction).
O aplicativo funciona bem no servidor de desenvolvimento fornecido pelo Flask, mas quando tento implantá -lo, recebo o seguinte erro no arquivo de log:
[Tue Mar 13 15:48:24 2012] [error] Traceback (most recent call last):
[Tue Mar 13 15:48:24 2012] [error] File "evdns.pxi", line 78, in gevent.core.__evdns_callback (gevent/core.c:6300)
[Tue Mar 13 15:48:24 2012] [error] File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 297, in switch_args
[Tue Mar 13 15:48:24 2012] [error] File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 290, in switch
[Tue Mar 13 15:48:24 2012] [error] File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 135, in get_hub
[Tue Mar 13 15:48:24 2012] [error] NotImplementedError: gevent is only usable from a single thread
Eu preciso do gevent porque estou usando o módulo assíncrono de solicitações python Para fazer solicitações HTTP simultâneas.Tentei pesquisar no Google, mas o único conselho que encontrei foi ligar
from gevent import monkey
monkey.patch_all()
algo que já faço no meu código.
O valor de WSGIDaemonProcess
é:
WSGIDaemonProcess myapp processes=5 python-path=/home/myusername/webapps/myapp/lib/python2.7 threads=1
Aqui está meu httpd.conf: http://pastebin.com/eWygicJH
Alguém tem algum conselho para resolver esse problema?
Solução
Parece que eu mesmo encontrei a solução.A seguinte diretiva resolveu meu problema:
WSGIApplicationGroup %{GLOBAL}
A ideia vem de outro responder onde é sugerido definir WSGIApplicationGroup como GLOBAL para resolver um problema com um processo WSGI que trava continuamente. Da documentação do WSGI:
Para forçar um aplicativo WSGI específico a ser executado no primeiro sub -intérprete Python criado quando o Python é inicializado, a diretiva WSGIApplicationGroup deve ser usada e o grupo definido como '%{global}'.
Não consigo entender completamente por que esta diretiva resolve meu problema, mas resolve.Ficarei mais do que feliz se alguém puder me explicar isso em inglês simples ;-)
Outras dicas
Tente substituir monkey.patch_all()
com monkey.patch_all(thread=False)
.Se for realmente o módulo de threading que está causando o problema quando corrigido, isso deve resolver o problema. request
não usa rosqueamento.
Eu postei abaixo a resposta em https://serverfault.com/a/869625/355861
Apache mod_wsgi atualmente não é compatível com gevent.Para o AWS Elastic Beanstalk com Apache, usei async_mode="threading" para Flask e funciona bem.Observe que o threading tem menos desempenho que o gevent.https://flask-socketio.readthedocs.io/en/latest/#deployment
app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="threading")
Observe que o Flask pode ser executado de forma independente com gevent.
app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="gevent")
if __name__ == '__main__':
HOST = '127.0.0.1'
PORT = 5055
socketio.run(app, port=PORT, host=HOST)
No entanto, você realmente deseja um servidor HTTP na frente dele, como o Gunicorn.