From a661ecab988f136c507fdf96de2d9a2650070a54 Mon Sep 17 00:00:00 2001 From: Sundaresan Rajangam Date: Thu, 6 Oct 2016 00:45:15 -0700 Subject: [PATCH] Use gevent.WSGIServer for http introspect Presently, pysandesh uses WSGIServer defined in wsgiref.simple_server for http introspect, whose poll_interval is 0.5 seconds by default. The poll_interval is used to check for server shutdown. Therefore, if the poll_interval is set to None, it requires external trigger such as connection to the socket to wakeup the select loop. Polling reduces the responsiveness and wastes cpu cycle. Use gevent.WSGIServer for http introspect to avoid the polling issue. Change-Id: Ic8cf8ec815c422be0d65e77247c67e7002bc91ad Closes-Bug: #1584160 (cherry picked from commit 8a0b129e482cfba1801ca92b4f36dd736c2bfe41) --- library/python/pysandesh/sandesh_http.py | 45 ++++++++++-------------- library/python/pysandesh/test/SConscript | 2 +- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/library/python/pysandesh/sandesh_http.py b/library/python/pysandesh/sandesh_http.py index db8c683f..828a4d38 100644 --- a/library/python/pysandesh/sandesh_http.py +++ b/library/python/pysandesh/sandesh_http.py @@ -18,7 +18,8 @@ if 'threading' in sys.modules: del sys.modules['threading'] from gevent import monkey; monkey.patch_all() -from wsgiref.simple_server import make_server, WSGIServer +from gevent.server import StreamServer +from gevent.pywsgi import WSGIServer import bottle import cStringIO from transport import TTransport @@ -27,16 +28,6 @@ import socket -class SandeshWSGIServer(WSGIServer): - # patch handle_error() which spews exception log to stdout that - # interferes/impacts the functioning of the supervisor. - def handle_error(self, request, client_address): - sys.stderr.write('Error while handling request from client %s'\ - % (str(client_address))) - import traceback - traceback.print_exc() -# end class SandeshWSGIServer - class SandeshHttp(object): _HTTP_SERVER_IP = '0.0.0.0' @@ -78,7 +69,7 @@ def __init__(self, sandesh, module, port, pkg_list): self._jquery_collapse_storage_js_path = None self._jquery_collapse_js_path = None self._jquery_1_8_1_js_path = None - self._svr = None + self._http_server = None try: imp_pysandesh = __import__('pysandesh') except ImportError: @@ -97,26 +88,28 @@ def __init__(self, sandesh, module, port, pkg_list): #end __init__ def stop_http_server(self): - if self._svr: - self._svr.shutdown() - self._svr = None + if self._http_server: + self._http_server.stop() + self._http_server = None self._logger.error('Stopped http server') + # end stop_http_server def start_http_server(self): try: - self._svr = make_server(SandeshHttp._HTTP_SERVER_IP, - self._http_port, - self._http_app, SandeshWSGIServer) + sock = StreamServer.get_listener((SandeshHttp._HTTP_SERVER_IP, + self._http_port), family=socket.AF_INET) except socket.error as e: - self._logger.error('Unable to open HTTP Port %d, %s' % (self._http_port, e)) + self._logger.error('Unable to open HTTP Port %d, %s' % + (self._http_port, e)) sys.exit() - self._http_port = self._svr.server_port - self._logger.error('Starting Introspect on HTTP Port %d' % self._http_port) - self._sandesh.record_port("http", self._http_port) - self._svr.allow_reuse_address = True - self._svr.serve_forever() - - #end start_http_server + else: + self._http_port = sock.getsockname()[1] + self._sandesh.record_port("http", self._http_port) + self._logger.error('Starting Introspect on HTTP Port %d' % + self._http_port) + self._http_server = WSGIServer(sock, self._http_app) + self._http_server.serve_forever() + # end start_http_server def get_port(self): return self._http_port diff --git a/library/python/pysandesh/test/SConscript b/library/python/pysandesh/test/SConscript index 4c18a392..48d122ba 100644 --- a/library/python/pysandesh/test/SConscript +++ b/library/python/pysandesh/test/SConscript @@ -49,7 +49,7 @@ env.Depends(test_modules_rules, gen_test_pkg) venv = env.setup_venv('pysandesh_test', 'pysandesh_test') env['env_venv'] = venv -pip_pkgs = ['greenlet==0.4.1', 'gevent==0.13.8', 'eventlet==0.9.17', +pip_pkgs = ['greenlet==0.4.1', 'gevent==1.1a2', 'eventlet==0.9.17', 'testtools==0.9.21', 'geventhttpclient==1.0a', 'bottle==0.11.6', 'mock==1.0.1']