예제 #1
0
 def get(self, queue, message_id, project=None):
     target = self._lookup(queue, project)
     if target:
         control = target.message_controller
         return control.get(queue, message_id=message_id,
                            project=project)
     raise errors.QueueDoesNotExist(queue, project)
예제 #2
0
파일: messages.py 프로젝트: jeffrey4l/zaqar
    def post(self, queue, messages, client_uuid, project=None):
        if not self._queue_ctrl.exists(queue, project):
            raise errors.QueueDoesNotExist(queue, project)

        msgset_key = utils.msgset_key(queue, project)
        counter_key = utils.scope_queue_index(queue, project,
                                              MESSAGE_RANK_COUNTER_SUFFIX)

        message_ids = []
        now = timeutils.utcnow_ts()

        with self._client.pipeline() as pipe:
            for msg in messages:
                prepared_msg = Message(
                    ttl=msg['ttl'],
                    created=now,
                    client_uuid=client_uuid,
                    claim_id=None,
                    claim_expires=now,
                    body=msg.get('body', {}),
                )

                prepared_msg.to_redis(pipe)
                message_ids.append(prepared_msg.id)

            pipe.execute()

        # NOTE(kgriffs): If this call fails, we will return
        # an error to the client and the messages will be
        # orphaned, but Redis will remove them when they
        # expire, so we will just pretend they don't exist
        # in that case.
        self._index_messages(msgset_key, counter_key, message_ids)

        return message_ids
예제 #3
0
파일: queues.py 프로젝트: jeffrey4l/zaqar
    def stats(self, name, project=None):
        if not self.exists(name, project=project):
            raise errors.QueueDoesNotExist(name, project)

        total = self._message_ctrl._count(name, project)

        if total:
            claimed = self._claim_ctrl._count_messages(name, project)
        else:
            claimed = 0

        message_stats = {
            'claimed': claimed,
            'free': total - claimed,
            'total': total,
        }

        if total:
            try:
                newest = self._message_ctrl.first(name, project, -1)
                oldest = self._message_ctrl.first(name, project, 1)
            except errors.QueueIsEmpty:
                pass
            else:
                message_stats['newest'] = newest
                message_stats['oldest'] = oldest

        return {'messages': message_stats}
예제 #4
0
 def set_metadata(self, name, metadata, project=None):
     target = self._lookup(name, project)
     if target:
         control = target.queue_controller
         return control.set_metadata(name, metadata=metadata,
                                     project=project)
     raise errors.QueueDoesNotExist(name, project)
예제 #5
0
파일: utils.py 프로젝트: jeffrey4l/zaqar
def get_qid(driver, queue, project):
    sel = sa.sql.select([tables.Queues.c.id],
                        sa.and_(tables.Queues.c.project == project,
                                tables.Queues.c.name == queue))
    try:
        return driver.get(sel)[0]
    except NoResult:
        raise errors.QueueDoesNotExist(queue, project)
예제 #6
0
 def post(self, queue, messages, client_uuid, project=None):
     target = self._lookup(queue, project)
     if target:
         control = target.message_controller
         return control.post(queue, project=project,
                             messages=messages,
                             client_uuid=client_uuid)
     raise errors.QueueDoesNotExist(queue, project)
예제 #7
0
파일: queues.py 프로젝트: jeffrey4l/zaqar
    def set_metadata(self, name, metadata, project=None):
        if not self.exists(name, project):
            raise errors.QueueDoesNotExist(name, project)

        key = utils.scope_queue_name(name, project)
        fields = {'m': self._packer(metadata)}

        self._client.hmset(key, fields)
예제 #8
0
파일: queues.py 프로젝트: jeffrey4l/zaqar
    def get_metadata(self, name, project=None):
        if not self.exists(name, project):
            raise errors.QueueDoesNotExist(name, project)

        queue_key = utils.scope_queue_name(name, project)
        metadata = self._get_queue_info(queue_key, b'm', None)[0]

        return self._unpacker(metadata)
예제 #9
0
파일: messages.py 프로젝트: jeffrey4l/zaqar
    def get(self, queue, message_id, project=None):
        if not self._queue_ctrl.exists(queue, project):
            raise errors.QueueDoesNotExist(queue, project)

        message = Message.from_redis(message_id, self._client)
        now = timeutils.utcnow_ts()

        if message and not utils.msg_expired_filter(message, now):
            return message.to_basic(now)
        else:
            raise errors.MessageDoesNotExist(message_id, queue, project)
예제 #10
0
    def get_metadata(self, name, project):
        if project is None:
            project = ''

        try:
            sel = sa.sql.select([tables.Queues.c.metadata],
                                sa.and_(tables.Queues.c.project == project,
                                        tables.Queues.c.name == name))
            return utils.json_decode(self.driver.get(sel)[0])
        except utils.NoResult:
            raise errors.QueueDoesNotExist(name, project)
예제 #11
0
파일: messages.py 프로젝트: jeffrey4l/zaqar
    def _list(self,
              queue,
              project=None,
              marker=None,
              limit=storage.DEFAULT_MESSAGES_PER_PAGE,
              echo=False,
              client_uuid=None,
              include_claimed=False,
              to_basic=True):

        if not self._queue_ctrl.exists(queue, project):
            raise errors.QueueDoesNotExist(queue, project)

        msgset_key = utils.msgset_key(queue, project)
        client = self._client

        if not marker and not include_claimed:
            # NOTE(kgriffs): Skip unclaimed messages at the head
            # of the queue; otherwise we would just filter them all
            # out and likely end up with an empty list to return.
            marker = self._find_first_unclaimed(queue, project, limit)
            start = client.zrank(msgset_key, marker) or 0
        else:
            rank = client.zrank(msgset_key, marker)
            start = rank + 1 if rank else 0

        message_ids = client.zrange(msgset_key, start, start + (limit - 1))

        messages = Message.from_redis_bulk(message_ids, client)

        # NOTE(prashanthr_): Build a list of filters for checking
        # the following:
        #
        #     1. Message is expired
        #     2. Message is claimed
        #     3. Message should not be echoed
        #
        now = timeutils.utcnow_ts()
        filters = [functools.partial(utils.msg_expired_filter, now=now)]

        if not include_claimed:
            filters.append(functools.partial(utils.msg_claimed_filter,
                                             now=now))

        if not echo:
            filters.append(
                functools.partial(utils.msg_echo_filter,
                                  client_uuid=client_uuid))

        marker = {}

        yield _filter_messages(messages, filters, to_basic, marker)
        yield marker['next']
예제 #12
0
    def set_metadata(self, name, metadata, project):
        if project is None:
            project = ''

        update = (tables.Queues.update().where(
            sa.and_(tables.Queues.c.project == project,
                    tables.Queues.c.name == name)).values(
                        metadata=utils.json_encode(metadata)))

        res = self.driver.run(update)

        try:
            if res.rowcount != 1:
                raise errors.QueueDoesNotExist(name, project)
        finally:
            res.close()
예제 #13
0
파일: messages.py 프로젝트: jeffrey4l/zaqar
    def bulk_get(self, queue, message_ids, project=None):
        if not self._queue_ctrl.exists(queue, project):
            raise errors.QueueDoesNotExist(queue, project)

        # NOTE(prashanthr_): Pipelining is used here purely
        # for performance.
        with self._client.pipeline() as pipe:
            for mid in message_ids:
                pipe.hgetall(mid)

            messages = pipe.execute()

        # NOTE(kgriffs): Skip messages that may have been deleted
        now = timeutils.utcnow_ts()
        return (Message.from_hmap(msg).to_basic(now) for msg in messages
                if msg)
예제 #14
0
파일: messages.py 프로젝트: jeffrey4l/zaqar
    def delete(self, queue, message_id, project=None, claim=None):
        if not self._queue_ctrl.exists(queue, project):
            raise errors.QueueDoesNotExist(queue, project)

        # NOTE(kgriffs): The message does not exist, so
        # it is essentially "already" deleted.
        if not self._exists(message_id):
            return

        # TODO(kgriffs): Create decorator for validating claim and message
        # IDs, since those are not checked at the transport layer. This
        # decorator should be applied to all relevant methods.
        if claim is not None:
            try:
                uuid.UUID(claim)
            except ValueError:
                raise errors.ClaimDoesNotExist(queue, project, claim)

        msg_claim = self._get_claim(message_id)
        is_claimed = (msg_claim is not None)

        # Authorize the request based on having the correct claim ID
        if claim is None:
            if is_claimed:
                raise errors.MessageIsClaimed(message_id)

        elif not is_claimed:
            raise errors.MessageNotClaimed(message_id)

        elif msg_claim['id'] != claim:
            if not self._claim_ctrl._exists(queue, claim, project):
                raise errors.ClaimDoesNotExist(queue, project, claim)

            raise errors.MessageNotClaimedBy(message_id, claim)

        msgset_key = utils.msgset_key(queue, project)

        with self._client.pipeline() as pipe:
            pipe.delete(message_id)
            pipe.zrem(msgset_key, message_id)

            if is_claimed:
                self._claim_ctrl._del_message(queue, project, msg_claim['id'],
                                              message_id, pipe)

            pipe.execute()
예제 #15
0
파일: messages.py 프로젝트: jeffrey4l/zaqar
    def bulk_delete(self, queue, message_ids, project=None):
        if not self._queue_ctrl.exists(queue, project):
            raise errors.QueueDoesNotExist(queue, project)

        msgset_key = utils.msgset_key(queue, project)

        with self._client.pipeline() as pipe:
            for mid in message_ids:
                if not self._exists(mid):
                    continue

                pipe.delete(mid)
                pipe.zrem(msgset_key, mid)

                msg_claim = self._get_claim(mid)
                if msg_claim is not None:
                    self._claim_ctrl._del_message(queue, project,
                                                  msg_claim['id'], mid, pipe)
            pipe.execute()
예제 #16
0
 def first(self, queue, project=None, sort=1):
     target = self._lookup(queue, project)
     if target:
         control = target.message_controller
         return control.first(queue, project=project, sort=sort)
     raise errors.QueueDoesNotExist(queue, project)
예제 #17
0
 def stats(self, name, project=None):
     target = self._lookup(name, project)
     if target:
         control = target.queue_controller
         return control.stats(name, project=project)
     raise errors.QueueDoesNotExist(name, project)