Skip to content

Instantly share code, notes, and snippets.

@maizy
Created April 2, 2015 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maizy/663f9f93b591618a2206 to your computer and use it in GitHub Desktop.
Save maizy/663f9f93b591618a2206 to your computer and use it in GitHub Desktop.
curl async client problems
# coding=utf-8
import httplib
import importlib
import logging
import re
import time
from lxml import etree
import tornado.autoreload
import tornado.web
import tornado.ioloop
import tornado.curl_httpclient
from tornado.options import options
from frontik import frontik_logging
from frontik.globals import global_stats
import frontik.producers.json_producer
import frontik.producers.xml_producer
from frontik.handler import ErrorHandler
import frontik.sentry
from frontik.util import make_get_request
# ...
class StatusHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
if self.get_argument('no_network_check', 'false') == 'true':
self.set_header('Content-Type', 'application/json; charset=UTF-8')
result = {
'pages served': global_stats.page_count,
'http requests made': global_stats.http_reqs_count,
'bytes from http requests': global_stats.http_reqs_size_sum,
}
cur_uptime = time.time() - global_stats.start_time
if cur_uptime < 60:
uptime_value = '{:.2f} seconds'.format(cur_uptime)
elif cur_uptime < 3600:
uptime_value = '{:.2f} minutes'.format(cur_uptime / 60)
else:
uptime_value = '{:.2f} hours and {:.2f} minutes'.format(cur_uptime / 3600, (cur_uptime % 3600) / 60)
result['uptime'] = uptime_value
import datetime
import functools
tornado.ioloop.IOLoop.current().add_timeout(
datetime.timedelta(seconds=15), # long response
functools.partial(self.finish, result)
)
# self.finish(result)
else:
request = make_get_request(
'http://{host}:{port}/status'.format(host='127.0.0.1' if options.host == '0.0.0.0' else options.host,
port=options.port),
data={'no_network_check': 'true'},
connect_timeout=0.5,
request_timeout=0.5, # do not wait for long responses
follow_redirects=False
)
def _request_ready(result):
if result.error is not None:
raise tornado.web.HTTPError(httplib.SERVICE_UNAVAILABLE)
self.finish(result.body)
self.application.curl_http_client.fetch(request, callback=_request_ready)
# ...
# ...
class FrontikApplication(tornado.web.Application):
class DefaultConfig(object):
pass
def __init__(self, **settings):
# ...
# set limit to 1
self.curl_http_client = tornado.curl_httpclient.CurlAsyncHTTPClient(max_clients=1)
# ...
@maizy
Copy link
Author

maizy commented Apr 2, 2015

for i in {1..10}; do http -ph 'http://127.0.0.1:8080/status' &; done;

in logs:

[I 15.04.02 15:22:56 tornado_util.server server:114] starting server on 127.0.0.1:8080
[E 15.04.02 15:22:59 tornado.access web:1854] 503 GET /status (127.0.0.1) 531.59ms
[E 15.04.02 15:22:59 tornado.access web:1854] 503 GET /status (127.0.0.1) 893.05ms
[E 15.04.02 15:23:00 tornado.access web:1854] 503 GET /status (127.0.0.1) 1396.77ms
[E 15.04.02 15:23:00 tornado.access web:1854] 503 GET /status (127.0.0.1) 1906.00ms
[E 15.04.02 15:23:01 tornado.access web:1854] 503 GET /status (127.0.0.1) 2357.55ms
[E 15.04.02 15:23:01 tornado.access web:1854] 503 GET /status (127.0.0.1) 2854.61ms
[E 15.04.02 15:23:02 tornado.access web:1854] 503 GET /status (127.0.0.1) 3359.57ms
[E 15.04.02 15:23:02 tornado.access web:1854] 503 GET /status (127.0.0.1) 3864.67ms
[E 15.04.02 15:23:03 tornado.access web:1854] 503 GET /status (127.0.0.1) 4371.35ms
[E 15.04.02 15:23:03 tornado.access web:1854] 503 GET /status (127.0.0.1) 4869.42ms
[I 15.04.02 15:23:13 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15007.98ms
[I 15.04.02 15:23:14 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15008.22ms
[I 15.04.02 15:23:14 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15005.70ms
[I 15.04.02 15:23:15 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15004.71ms
[I 15.04.02 15:23:15 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15008.99ms
[I 15.04.02 15:23:16 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15006.30ms
[I 15.04.02 15:23:16 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15007.07ms
[I 15.04.02 15:23:17 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15005.11ms
[I 15.04.02 15:23:17 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15005.39ms
[I 15.04.02 15:23:18 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15003.28ms

@maizy
Copy link
Author

maizy commented Apr 2, 2015

Тот же самый код с подменой на AsyncHTTPClient (встроенный написанный на python) работает правильно:

class FrontikApplication(tornado.web.Application):
    def __init__(self, **settings):
        # ...
        import tornado.httpclient
        self.curl_http_client = tornado.httpclient.AsyncHTTPClient(max_clients=1)
        # ...
[I 15.04.02 16:55:30 tornado_util.server server:114] starting server on 127.0.0.1:8080
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 1 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 2 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 3 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 4 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 5 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 6 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 7 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 8 queued requests.
[D 15.04.02 16:55:41 tornado.general simple_httpclient:107] max_clients limit reached, request queued. 1 active, 9 queued requests.
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 507.20ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 501.84ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 501.06ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 501.31ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 501.82ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 501.06ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 501.29ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 502.04ms
[E 15.04.02 16:55:41 tornado.access web:1854] 503 GET /status (127.0.0.1) 502.12ms
[E 15.04.02 16:55:42 tornado.access web:1854] 503 GET /status (127.0.0.1) 1010.47ms
[I 15.04.02 16:55:56 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15007.35ms
[I 15.04.02 16:55:56 tornado.access web:1854] 200 GET /status?no_network_check=true (127.0.0.1) 15005.84ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment