Merge "NSX-v3 multi-manager round robin scheduling"

This commit is contained in:
Jenkins 2016-02-09 19:13:03 +00:00 committed by Gerrit Code Review
commit 5d33132a2e
2 changed files with 37 additions and 12 deletions

View File

@ -18,8 +18,8 @@ import contextlib
import copy
import datetime
import eventlet
import itertools
import logging
import random
import requests
import six
import urlparse
@ -263,6 +263,9 @@ class ClusteredAPI(object):
endpoint = Endpoint(provider, pool)
self._endpoints[provider.id] = endpoint
# service requests using round robin
self._endpoint_schedule = itertools.cycle(self._endpoints.values())
# duck type to proxy http invocations
for method in ClusteredAPI._HTTP_VERBS:
setattr(self, method, self._proxy_stub(method))
@ -339,18 +342,13 @@ class ClusteredAPI(object):
{'ep': endpoint, 'err': e})
def _select_endpoint(self):
connected = {}
for provider_id, endpoint in self._endpoints.items():
# check for UP state until exhausting all endpoints
seen, total = 0, len(self._endpoints.values())
while seen < total:
endpoint = next(self._endpoint_schedule)
if endpoint.state == EndpointState.UP:
connected[provider_id] = endpoint
if endpoint.pool.free():
# connection can be used now
return endpoint
# no free connections; randomly select a connected endpoint
# which will likely wait on pool.item() until a connection frees up
return (connected[random.choice(connected.keys())]
if connected else None)
return endpoint
seen += 1
def endpoint_for_connection(self, conn):
# check all endpoint pools

View File

@ -211,3 +211,30 @@ class ClusteredAPITestCase(nsxlib_testcase.NsxClientTestCase):
api._validate = mock.Mock()
self.assertRaises(nsx_exc.ServiceClusterUnavailable,
api.get, 'api/v1/transport-zones')
def test_cluster_round_robin_servicing(self):
conf_managers = ['8.9.10.11', '9.10.11.12', '10.11.12.13']
cfg.CONF.set_override(
'nsx_api_managers', conf_managers, 'nsx_v3')
api = self.mock_nsx_clustered_api()
api._validate = mock.Mock()
eps = api._endpoints.values()
def _get_schedule(num_eps):
return [api._select_endpoint() for i in range(num_eps)]
self.assertEqual(_get_schedule(3), eps)
self.assertEqual(_get_schedule(6), [eps[0], eps[1], eps[2],
eps[0], eps[1], eps[2]])
eps[0]._state = cluster.EndpointState.DOWN
self.assertEqual(_get_schedule(4), [eps[1], eps[2], eps[1], eps[2]])
eps[1]._state = cluster.EndpointState.DOWN
self.assertEqual(_get_schedule(2), [eps[2], eps[2]])
eps[0]._state = cluster.EndpointState.UP
self.assertEqual(_get_schedule(4), [eps[0], eps[2], eps[0], eps[2]])