First of all, sorry for my poor English. In my project, I have many network I / O requests. The main data is stored in other projects, and access is provided through the web API (JSON / XML) survey. We use these APIs for each new user session (to obtain user information). And sometimes we have a problem with waiting for an answer. We use nginx + uwsgi + django. As you know, Django is synchronous (or blocking). We use uwsgi with a multi-threaded solution to solve the IO network wait problem. I decided to read about gevent. I understand the difference between collaborative and proactive multitasking. And I was hoping that gevent is the best solution, and then uwsgi themes for this problem (bottleneck in the I / O network). But the results were almost the same. Sometimes gevent was weaker. Maybe somewhere I'm wrong. Tell me please.
Here are uwsgi configuration examples. GEvent:
$ uwsgi --http :8001 --module ugtest.wsgi --gevent 40 --gevent-monkey-patch
Threading:
$ uwsgi --http :8001 --module ugtest.wsgi --enable-threads --threads 40
Controller example:
def simple_test_action(request): # get data from API without parsing (only for simple I/O test) data = _get_data_by_url(API_URL) return JsonResponse(data, safe=False) import httplib from urlparse import urlparse def _get_data_by_url(url): u = urlparse(url) if str(u.scheme).strip().lower() == 'https': conn = httplib.HTTPSConnection(u.netloc) else: conn = httplib.HTTPConnection(u.netloc) path_with_params = '%s?%s' % (u.path, u.query, ) conn.request("GET", path_with_params) resp = conn.getresponse() print resp.status, resp.reason body = resp.read() return body
Test (with geventhttpclient ):
def get_info(i): url = URL('http://localhost:8001/simpletestaction/') http = HTTPClient.from_url(url, concurrency=100, connection_timeout=60, network_timeout=60) try: response = http.get(url.request_uri) s = response.status_code body = response.read() finally: http.close() dt_start = dt.now() print 'Start: %s' % dt_start threads = [gevent.spawn(get_info, i) for i in xrange(401)] gevent.joinall(threads) dt_end = dt.now() print 'End: %s' % dt_end print dt_end-dt_start
In both cases, I have the same time. What are the benefits of gevent / greenlets and collaborative multitasking in a similar problem (API proxy)?
OLMER source share