2012-03-13 3 views
4

У меня возникла проблема с развертыванием моего приложения Flask с Apache (mod_wsgi) и gevent на общем хостинге (Webfaction).Почему gevent в приложении Flask с Apache + mod_wsgi поднимает NotImplementedError?

Приложение отлично работает на сервере разработки, представленной Колба, но когда я попытаться развернуть его я получаю следующее сообщение об ошибке в файле журнала:

[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 

мне нужно GEvent, потому что я использую python-requests' async module до сделать одновременные HTTP-запросы. Я попытался Google вокруг, но единственный совет, который я нашел, чтобы позвонить

from gevent import monkey 
monkey.patch_all() 

то, что я уже делать в моем коде.

Значение WSGIDaemonProcess является:

WSGIDaemonProcess myapp processes=5 python-path=/home/myusername/webapps/myapp/lib/python2.7 threads=1 

Вот мой httpd.conf: http://pastebin.com/eWygicJH

Кто-нибудь имеет какие-либо советы, чтобы решить эту проблему?

+0

который является значением WSGIDaemonProcess на вашем httpd.conf? – Masci

+1

Возможно, из-за того, что gevent в моем опыте немного расстроен, если он получает доступ к обезьянному патчу для модуля потоков Python после того, как кто-то еще его импортировал и использовал его определенным образом. Не вызывает у меня никаких проблем с некоторыми вещами. Однако у меня не было возможности вникать в проблему. –

+0

@Masci Я обновил вопрос по ссылке на мой httpd.conf и значение WSGIDaemonProcess – raben

ответ

2

Кажется, я нашел решение самостоятельно. Следующая директива решить мою проблему:

WSGIApplicationGroup %{GLOBAL} 

Идея исходит от другого answer, где предлагается установить WSGIApplicationGroup для GLOBAL, чтобы решить проблему с процессом WSGI, которые держат сбой. From WSGI documentation:

Чтобы заставить конкретного приложения WSGI для запуска в первом же суб интерпретатор Python создается, когда Python инициализируется, директива WSGIApplicationGroup должна быть использована и группа, в «% {GLOBAL}» ,

Не могу полностью понять, почему эта директива решает мою проблему, но она делает. Я буду более чем счастлив, если кто-то может объяснить мне это в простом английском ;-)

+0

см. [Why-is-method-that-uses-gevent-in-a-mod-wsgi-deployed-flask-api-raise-error] (http://serverfault.com/questions/754841/why-is -method-that-uses-gevent-in-a-mod-wsgi-deployed-flask-api-raise-error-ab) ... извините, что так поздно, но у меня наконец есть ответ. –

+0

Зачем -1 для этого? Соответствующий ответ на вопрос «Не могу полностью понять, почему эта директива решает мою проблему, но она делает», заключается в том, что «я нашел ответ здесь: почему директива WSGIApplicationGroup% {GLOBAL} работает для создания новых потоков В двух словах: WSGIApplicationGroup:.. Установите исполнение для работы под тем же интерпретатор Python (первый созданный) Таким образом, по умолчанию, каждый новый поток, должно быть, не используется один и тот же экземпляр питон интерпретатор для uWSGI, эквивалентный метод является добавьте это в ваш .ini-файл: single-interpreter = true " –

1

Попробуйте заменить monkey.patch_all() на monkey.patch_all(thread=False). Если это действительно модуль потоковой передачи, который вызывает проблему при исправлении, это должно решить проблему. request не используется резьба.

+0

Спасибо Simon, я попробовал это решение, но я все равно получаю ту же ошибку. – raben

0

Я отправил ниже ответ на https://serverfault.com/a/869625/355861

апач mod_wsgi в настоящее время не совместимы с GEvent. Для AWS эластичного бобового стежка с Apache я использовал async_mode = "threading" для Flask, и он работает хорошо. Обратите внимание, что потоки имеют меньшую производительность, чем gevent. https://flask-socketio.readthedocs.io/en/latest/#deployment

app = Flask(__name__,static_folder='static') 
socketio = SocketIO(app, async_mode="threading") 

Обратите внимание, что колба может работать автономно с 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) 

Однако вы действительно хотите, чтобы перед ним был HTTP-сервер, такой как Gunicorn.