Skip to content

Commit

Permalink
Use gevent.WSGIServer for http introspect
Browse files Browse the repository at this point in the history
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 8a0b129)
  • Loading branch information
Sundaresan Rajangam committed Oct 6, 2016
1 parent d366513 commit d5b9547
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 27 deletions.
45 changes: 19 additions & 26 deletions library/python/pysandesh/sandesh_http.py
Expand Up @@ -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
Expand All @@ -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'
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion library/python/pysandesh/test/SConscript
Expand Up @@ -50,7 +50,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']

Expand Down

0 comments on commit d5b9547

Please sign in to comment.