Move create of ComputeAPI object in websocketproxy
Currently, we create a compute.rpcapi.ComputeAPI object during NovaProxyRequestHandler.__init__ in order to make calls to nova-compute for console token authorizations (port validation). This is problematic in the event that we receive a TCP RST as it results in constructing a ComputeAPI object only to throw it away and a large number of TCP RST sent can cause excessive resource consumption. This moves the creation of the ComputeAPI object from __init__ to being lazily instantiated upon first use by access of a property, thus avoiding creation of ComputeAPI objects when we receive TCP RST messages. Closes-Bug: #1816727 Change-Id: I3fe5540ea460fb32767b5e681295fdaf89ce17c5 (cherry picked from commit e4fa061f17353f49615d4850b562699d55a0641b) (cherry picked from commit b1b28169af9f835f5b99a4d70d1c0eff2d9fc2f4)
This commit is contained in:
parent
9bb78d5765
commit
7766027c89
nova
@ -304,12 +304,18 @@ class NovaProxyRequestHandlerBase(object):
|
||||
class NovaProxyRequestHandler(NovaProxyRequestHandlerBase,
|
||||
websockify.ProxyRequestHandler):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Order matters here. ProxyRequestHandler.__init__() will eventually
|
||||
# call new_websocket_client() and we need self.compute_rpcapi set
|
||||
# before then.
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
self._compute_rpcapi = None
|
||||
websockify.ProxyRequestHandler.__init__(self, *args, **kwargs)
|
||||
|
||||
@property
|
||||
def compute_rpcapi(self):
|
||||
# Lazy load the rpcapi/ComputeAPI upon first use for this connection.
|
||||
# This way, if we receive a TCP RST, we will not create a ComputeAPI
|
||||
# object we won't use.
|
||||
if not self._compute_rpcapi:
|
||||
self._compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
return self._compute_rpcapi
|
||||
|
||||
def socket(self, *args, **kwargs):
|
||||
return websockify.WebSocketServer.socket(*args, **kwargs)
|
||||
|
||||
|
@ -706,6 +706,16 @@ class NovaProxyRequestHandlerBaseTestCase(test.NoDBTestCase):
|
||||
self.wh.socket.assert_called_with('node1', 10000, connect=True)
|
||||
self.wh.do_proxy.assert_called_with('<socket>')
|
||||
|
||||
def test_tcp_rst_no_compute_rpcapi(self):
|
||||
# Tests that we don't create a ComputeAPI object if we receive a
|
||||
# TCP RST message. Simulate by raising the socket.err upon recv.
|
||||
err = socket.error('[Errno 104] Connection reset by peer')
|
||||
self.wh.socket.recv.side_effect = err
|
||||
conn = mock.MagicMock()
|
||||
address = mock.MagicMock()
|
||||
self.wh.server.top_new_client(conn, address)
|
||||
self.assertIsNone(self.wh._compute_rpcapi)
|
||||
|
||||
|
||||
class NovaWebsocketSecurityProxyTestCase(test.NoDBTestCase):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user