Exemple #1
0
    def on_put(self, request, response, queue):
        """Create a queue in the catalogue, then forwards to marconi.

        This is the only time marconi proxy ever needs to select a
        partition for a queue. The association is created in the
        catalogue. This should also be the only time
        partition.weighted_select is ever called.

        :raises: HTTPInternalServerError - if no partitions are registered
        """
        project = helpers.get_project(request)

        # NOTE(cpp-cabrera): if we've already registered a queue,
        # don't try to create it again, because it will duplicate it
        # across partitions.
        #
        # There exists a race condition here, but it is benign. It's
        # possible that after the existence check has succeeded,
        # another request may succeed in DELETEing a queue. In this
        # scenario, the queue will be recreated on another partition,
        # which is reasonable, since the user meant to both DELETE and
        # PUT That queue.
        if lookup.exists(project, queue,
                         self._catalogue, self._cache):
            response.status = falcon.HTTP_204
            return

        target = partition.weighted_select(self._partitions.list())
        if target is None:
            LOG.error('No partitions registered')
            raise falcon.HTTPInternalServerError(
                "No partitions registered",
                "Contact the system administrator for more details."
            )
        host = target['hosts'][0]
        resp = helpers.forward(host, request)

        # NOTE(cpp-cabrera): only catalogue a queue if it was created
        if resp.status_code == 201:
            self._catalogue.insert(project, queue, target['name'],
                                   host)

        response.set_headers(helpers.capitalized(resp.headers))
        response.status = http.status(resp.status_code)
        response.body = resp.content
Exemple #2
0
    def on_get(self, request, response):
        LOG.debug('GET v1')
        partition = None
        try:
            partition = next(self._partitions.list())
        except StopIteration:
            LOG.error('GET v1 - no partitions registered')
            raise falcon.HTTPServiceUnavailable(
                "No partitions found",
                "Register some partitions",
                retry_after=120
            )

        host = partition['hosts'][0]
        resp = helpers.forward(host, request)

        response.set_headers(helpers.capitalized(resp.headers))
        response.status = http.status(resp.status_code)
        response.body = resp.content
Exemple #3
0
    def on_put(self, request, response, queue):
        """Create a queue in the catalogue, then forwards to marconi.

        This is the only time marconi proxy ever needs to select a
        partition for a queue. The association is created in the
        catalogue. This should also be the only time
        partition.weighted_select is ever called.

        :raises: HTTPInternalServerError - if no partitions are registered
        """
        project = helpers.get_project(request)

        # NOTE(cpp-cabrera): if we've already registered a queue,
        # don't try to create it again, because it will duplicate it
        # across partitions.
        #
        # There exists a race condition here, but it is benign. It's
        # possible that after the existence check has succeeded,
        # another request may succeed in DELETEing a queue. In this
        # scenario, the queue will be recreated on another partition,
        # which is reasonable, since the user meant to both DELETE and
        # PUT That queue.
        if lookup.exists(project, queue, self._catalogue, self._cache):
            response.status = falcon.HTTP_204
            return

        target = partition.weighted_select(self._partitions.list())
        if target is None:
            LOG.error('No partitions registered')
            raise falcon.HTTPInternalServerError(
                "No partitions registered",
                "Contact the system administrator for more details.")
        host = target['hosts'][0]
        resp = helpers.forward(host, request)

        # NOTE(cpp-cabrera): only catalogue a queue if it was created
        if resp.status_code == 201:
            self._catalogue.insert(project, queue, target['name'], host)

        response.set_headers(helpers.capitalized(resp.headers))
        response.status = http.status(resp.status_code)
        response.body = resp.content
Exemple #4
0
    def forward(self, request, response, queue, **kwargs):
        """Forwards requests in a selector-driven fashion."""
        project = helpers.get_project(request)
        LOG.debug('FORWARD - project/queue: {0}/{1}'.format(
            project, queue
        ))

        partition = lookup.partition(project, queue,
                                     self._catalogue,
                                     self._cache)

        # NOTE(cpp-cabrera): we tried to look up a catalogue
        # entry and it failed. This happens if the associated
        # queue doesn't exist under that project.
        if not partition:
            LOG.debug('Catalogue entry not found')
            raise falcon.HTTPNotFound()

        hosts = lookup.hosts(partition, self._partitions, self._cache)

        # NOTE(cpp-cabrera): we tried to look up a partition, and it
        # failed. This only happens if a partition is deleted from
        # the primary store between here and the last call.
        if not hosts:
            LOG.debug('Partition not found')
            raise falcon.HTTPNotFound()

        # round robin to choose the desired host
        host = self._selector.next(partition, hosts)

        # send the request, update the response
        resp = helpers.forward(host, request)

        # NOTE(zyuan): normalize the lower-case header from
        # `requests` to Caml-Case and forward the headers back
        response.set_headers(helpers.capitalized(resp.headers))
        response.status = http.status(resp.status_code)
        response.body = resp.content

        # NOTE(cpp-cabrera): in case responder must do more afterwards
        return resp
Exemple #5
0
    def forward(self, request, response, queue, **kwargs):
        """Forwards requests in a selector-driven fashion."""
        project = helpers.get_project(request)
        LOG.debug('FORWARD - project/queue: {0}/{1}'.format(project, queue))

        partition = lookup.partition(project, queue, self._catalogue,
                                     self._cache)

        # NOTE(cpp-cabrera): we tried to look up a catalogue
        # entry and it failed. This happens if the associated
        # queue doesn't exist under that project.
        if not partition:
            LOG.debug('Catalogue entry not found')
            raise falcon.HTTPNotFound()

        hosts = lookup.hosts(partition, self._partitions, self._cache)

        # NOTE(cpp-cabrera): we tried to look up a partition, and it
        # failed. This only happens if a partition is deleted from
        # the primary store between here and the last call.
        if not hosts:
            LOG.debug('Partition not found')
            raise falcon.HTTPNotFound()

        # round robin to choose the desired host
        host = self._selector.next(partition, hosts)

        # send the request, update the response
        resp = helpers.forward(host, request)

        # NOTE(zyuan): normalize the lower-case header from
        # `requests` to Caml-Case and forward the headers back
        response.set_headers(helpers.capitalized(resp.headers))
        response.status = http.status(resp.status_code)
        response.body = resp.content

        # NOTE(cpp-cabrera): in case responder must do more afterwards
        return resp