def register(self, queue, project=None, flavor=None): """Register a new queue in the pool catalog. This method should be called whenever a new queue is being created, and will create an entry in the pool catalog for the given queue. After using this method to register the queue in the catalog, the caller should call `lookup()` to get a reference to a storage driver which will allow interacting with the queue's assigned backend pool. :param queue: Name of the new queue to assign to a pool :type queue: six.text_type :param project: Project to which the queue belongs, or None for the "global" or "generic" project. :type project: six.text_type :param flavor: Flavor for the queue (OPTIONAL) :type flavor: six.text_type :raises: NoPoolFound """ # NOTE(cpp-cabrera): only register a queue if the entry # doesn't exist if not self._catalogue_ctrl.exists(project, queue): if flavor is not None: flavor = self._flavor_ctrl.get(flavor, project=project) pools = self._pools_ctrl.get_pools_by_group( group=flavor['pool_group'], detailed=True) pool = select.weighted(pools) pool = pool and pool['name'] or None else: # NOTE(flaper87): Get pools assigned to the default # group `None`. We should consider adding a `default_group` # option in the future. pools = self._pools_ctrl.get_pools_by_group(detailed=True) pool = select.weighted(pools) pool = pool and pool['name'] or None if not pool: # NOTE(flaper87): We used to raise NoPoolFound in this # case but we've decided to support automatic pool # creation. Note that we're now returning and the queue # is not being registered in the catalogue. This is done # on purpose since no pool exists and the "dummy" pool # doesn't exist in the storage if self.lookup(queue, project) is not None: return raise errors.NoPoolFound() self._catalogue_ctrl.insert(project, queue, pool)
def register(self, queue, project=None): """Register a new queue in the pool catalog. This method should be called whenever a new queue is being created, and will create an entry in the pool catalog for the given queue. After using this method to register the queue in the catalog, the caller should call `lookup()` to get a reference to a storage driver which will allow interacting with the queue's assigned backend pool. :param queue: Name of the new queue to assign to a pool :type queue: six.text_type :param project: Project to which the queue belongs, or None for the "global" or "generic" project. :type project: six.text_type :raises: NoPoolFound """ # NOTE(cpp-cabrera): only register a queue if the entry # doesn't exist if not self._catalogue_ctrl.exists(project, queue): # NOTE(cpp-cabrera): limit=0 implies unlimited - select from # all pools pool = select.weighted(self._pools_ctrl.list(limit=0)) if not pool: raise errors.NoPoolFound() self._catalogue_ctrl.insert(project, queue, pool['name'])
def test_weighted_boundaries(self): objs = [{'weight': 1, 'name': str(i)} for i in range(3)] for i in range(len(objs)): fixed_gen = lambda x, y: i self.assertEqual(objs[i], select.weighted(objs, generator=fixed_gen))
def test_weighted_returns_last_if_selector_is_sum_minus_one(self): objs = [{'weight': 10, 'name': str(i)} for i in range(10)] sum_weights = sum([o['weight'] for o in objs]) capped_gen = lambda x, y: sum_weights - 1 self.assertEqual(objs[-1], select.weighted(objs, generator=capped_gen))
def test_weighted_returns_first_if_selector_is_zero(self): objs = [{'weight': 10, 'name': str(i)} for i in range(10)] zero_gen = lambda x, y: 0 self.assertEqual(objs[0], select.weighted(objs, generator=zero_gen))
def test_weighted_returns_none_if_selector_oob(self): objs = [{'weight': 10, 'name': str(i)} for i in range(10)] sum_weights = sum([o['weight'] for o in objs]) capped_gen = lambda x, y: sum_weights self.assertIsNone(select.weighted(objs, generator=capped_gen))
def test_weighted_returns_an_object_it_was_given(self): objs = [{'weight': 10, 'name': str(i)} for i in range(10)] ret = select.weighted(objs) self.assertIn(ret, objs)
def test_weighted_ignores_zero_weight_objs(self): objs = [{'weight': 0, 'name': str(i)} for i in range(2)] expect = {'weight': 1, 'name': 'theone'} objs.append(expect) self.assertEqual(expect, select.weighted(objs))
def test_weighted_returns_none_if_objs_have_zero_weight(self): objs = [{'weight': 0, 'name': str(i)} for i in range(2)] self.assertIsNone(select.weighted(objs))
def test_weighted_returns_none_if_no_objs(self): self.assertIsNone(select.weighted([]))
def register(self, queue, project=None, flavor=None): """Register a new queue in the pool catalog. This method should be called whenever a new queue is being created, and will create an entry in the pool catalog for the given queue. After using this method to register the queue in the catalog, the caller should call `lookup()` to get a reference to a storage driver which will allow interacting with the queue's assigned backend pool. :param queue: Name of the new queue to assign to a pool :type queue: six.text_type :param project: Project to which the queue belongs, or None for the "global" or "generic" project. :type project: six.text_type :param flavor: Flavor for the queue (OPTIONAL) :type flavor: six.text_type :raises NoPoolFound: if not found """ # NOTE(gengchc): if exist, get queue's pool.flavor: # if queue's pool.flavor is different, first delete it and add it. # Otherwise, if the flavor in the meteredata of the queue is # modified, the catalog will be inconsistent. if self._catalogue_ctrl.exists(project, queue): catalogue = self._catalogue_ctrl.get(project, queue) oldpoolids = catalogue['pool'] oldpool = self._pools_ctrl.get(oldpoolids) oldflavor = oldpool['flavor'] msgtmpl = _(u'register queue to pool: old flavor: %(oldflavor)s ' ', new flavor: %(flavor)s') LOG.info(msgtmpl, {'oldflavor': oldflavor, 'flavor': flavor}) if oldpool['flavor'] != flavor: self._catalogue_ctrl.delete(project, queue) if not self._catalogue_ctrl.exists(project, queue): if flavor is not None: flavor = self._flavor_ctrl.get(flavor, project=project) pools = self._pools_ctrl.get_pools_by_flavor( flavor=flavor, detailed=True) pool = select.weighted(pools) pool = pool and pool['name'] or None msgtmpl = _(u'register queue to pool: new flavor:%(flavor)s') LOG.info(msgtmpl, {'flavor': flavor.get('name', None)}) else: # NOTE(flaper87): Get pools assigned to the default # group `None`. We should consider adding a `default_group` # option in the future. pools = self._pools_ctrl.get_pools_by_flavor(detailed=True) pool = select.weighted(pools) pool = pool and pool['name'] or None if not pool: # NOTE(flaper87): We used to raise NoPoolFound in this # case but we've decided to support automatic pool # creation. Note that we're now returning and the queue # is not being registered in the catalogue. This is done # on purpose since no pool exists and the "dummy" pool # doesn't exist in the storage if self.lookup(queue, project) is not None: return raise errors.NoPoolFound() msgtmpl = _(u'register queue to pool: new flavor: None') LOG.info(msgtmpl) msgtmpl = _(u'register queue: project:%(project)s' ' queue:%(queue)s pool:%(pool)s') LOG.info(msgtmpl, {'project': project, 'queue': queue, 'pool': pool}) self._catalogue_ctrl.insert(project, queue, pool)