1

I am trying to deploy a Flask api via Apache/mod_wsgi. The api uses Gevent to provide concurrency for a recursive method. However, it is throwing the following error

[Mon Feb 08 12:05:37 2016] [error] error: cannot switch to a different thread
[Mon Feb 08 12:05:37 2016] [error] <callback at 0x1094ee350 args=()> failed with error

The entire api runs just fine using Gevent when run using Pycharm's built-in web server, and the api runs fine deployed using Apache/mod_wsgi when I don't use gevent to provide concurrency.

I assume that this should be runnable in Apache, but I so far have not been able to find a solution. I keep seeing mention of monkey patching, so I added this line to the module in which gevent is called

from gevent import monkey; monkey.patch_all()

but, that did not seem to help.

I found this bit on standalone WSGI containers in the Flask documentation (http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/):

Gevent is a coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of libevent event loop:

from gevent.wsgi import WSGIServer
from yourapplication import app

http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()

It also says that

There are popular servers written in Python that contain WSGI applications and serve HTTP. These servers stand alone when they run; you can proxy to them from your web server. Note the section on Proxy Setups if you run into issues.

Do I need to ditch use of mod_wsgi and use Gevent's built in WSGI server and then proxy it via Apache? This would be a royal PITA, especially to deal with CORS issues (we have a web UI that accesses the api on the same server, and proxying from a different port would cause cross origin issues galore - unless someone can convince me otherwise).

Any insight on what to try next would be most appreciated.

3 Answers 3

2

apache mod_wsgi is not currently compatible with gevent. For AWS elastic beanstalk with Apache, I used async_mode="threading" for Flask and it works well. Note, threading has less performance than gevent.
https://flask-socketio.readthedocs.io/en/latest/#deployment

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

Note that Flask can run standalone with 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)

However, you really want an HTTP server in front of it such as Gunicorn.

1
  • Actually, I ended up using uwsgi with NginX. Aug 22, 2017 at 20:23
0

I just found a similar thread to mine here https://stackoverflow.com/questions/9692089/why-gevent-on-a-flask-app-with-apache-mod-wsgi-is-raising-notimplementederror that has the solution.

To do what I need I have to add the directive WSGIApplicationGroup %{GLOBAL} to my Apache conf. I too am curious as to why this solves the problem.

0

I found the answer here: Why does the directive WSGIApplicationGroup %{GLOBAL} work for creating new threads

In a nutshell:

WSGIApplicationGroup: Set the execution to run under the same Python interpreter (the first created).

So, by default, each new thread must've not used the same python interpreter instance.

For uWSGI, the equivalent method is to add this to your .ini file:

single-interpreter = true

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .