def delete(self, queue_name, message_id, project=None, claim=None): # NOTE(cpp-cabrera): return early - this is an invalid message # id so we won't be able to find it any way mid = utils.to_oid(message_id) if mid is None: return collection = self._collection(queue_name, project) query = { '_id': mid, PROJ_QUEUE: utils.scope_queue_name(queue_name, project), } # NOTE(cpp-cabrera): return early - the user gaves us an # invalid claim id and that renders the rest of this # request moot cid = utils.to_oid(claim) if cid is None: return now = timeutils.utcnow_ts() cursor = collection.find(query).hint(ID_INDEX_FIELDS) try: message = next(cursor) except StopIteration: return is_claimed = (message['c']['id'] is not None and message['c']['e'] > now) if claim is None: if is_claimed: raise errors.MessageIsClaimed(message_id) else: if message['c']['id'] != cid: # NOTE(kgriffs): Read from primary in case the message # was just barely claimed, and claim hasn't made it to # the secondary. pref = pymongo.read_preferences.ReadPreference.PRIMARY message = collection.find_one(query, read_preference=pref) if message['c']['id'] != cid: raise errors.MessageIsClaimedBy(message_id, claim) collection.remove(query['_id'], w=0)
def delete(self, queue_name, message_id, project=None, claim=None): # NOTE(cpp-cabrera): return early - this is an invalid message # id so we won't be able to find it any way mid = utils.to_oid(message_id) if mid is None: return collection = self._collection(queue_name, project) query = { '_id': mid, PROJ_QUEUE: utils.scope_queue_name(queue_name, project), } # NOTE(cpp-cabrera): return early - the user gaves us an # invalid claim id and that renders the rest of this # request moot cid = utils.to_oid(claim) if cid is None: return now = timeutils.utcnow_ts() cursor = collection.find(query).hint(ID_INDEX_FIELDS) try: message = next(cursor) except StopIteration: return is_claimed = (message['c']['id'] is not None and message['c']['e'] > now) if claim is None: if is_claimed: raise errors.MessageIsClaimed(message_id) else: if message['c']['id'] != cid: # NOTE(kgriffs): Read from primary in case the message # was just barely claimed, and claim hasn't made it to # the secondary. pref = pymongo.read_preferences.ReadPreference.PRIMARY message = collection.find_one(query, read_preference=pref) if message['c']['id'] != cid: raise errors.MessageIsClaimedBy(message_id, claim) collection.remove(query['_id'], w=0)
def _unclaim(self, queue_name, claim_id, project=None): cid = utils.to_oid(claim_id) # NOTE(cpp-cabrera): early abort - avoid a DB query if we're handling # an invalid ID if cid is None: return # NOTE(cpp-cabrera): unclaim by setting the claim ID to None # and the claim expiration time to now now = timeutils.utcnow_ts() scope = utils.scope_queue_name(queue_name, project) collection = self._collection(queue_name, project) collection.update({ PROJ_QUEUE: scope, 'c.id': cid }, {'$set': { 'c': { 'id': None, 'e': now } }}, upsert=False, multi=True)
def get(self, queue_name, message_id, project=None): """Gets a single message by ID. :raises: exceptions.MessageDoesNotExist """ mid = utils.to_oid(message_id) if mid is None: raise exceptions.MessageDoesNotExist(message_id, queue_name, project) now = timeutils.utcnow_ts() query = { '_id': mid, 'p': project, 'q': queue_name, 'e': {'$gt': now} } message = list(self._col.find(query).limit(1).hint(ID_INDEX_FIELDS)) if not message: raise exceptions.MessageDoesNotExist(message_id, queue_name, project) return _basic_message(message[0], now)
def update(self, queue, claim_id, metadata, project=None): cid = utils.to_oid(claim_id) if cid is None: raise exceptions.ClaimDoesNotExist(claim_id, queue, project) now = timeutils.utcnow_ts() ttl = int(metadata.get('ttl', 60)) expires = now + ttl msg_ctrl = self.driver.message_controller claimed = msg_ctrl._claimed(queue, cid, expires=now, limit=1, project=project) try: next(claimed) except StopIteration: raise exceptions.ClaimDoesNotExist(claim_id, queue, project) meta = { 'id': cid, 't': ttl, 'e': expires, } # TODO(kgriffs): Create methods for these so we don't interact # with the messages collection directly (loose coupling) scope = utils.scope_queue_name(queue, project) collection = msg_ctrl._collection(queue, project) collection.update({ 'p_q': scope, 'c.id': cid }, {'$set': { 'c': meta }}, upsert=False, multi=True) # NOTE(flaper87): Dirty hack! # This sets the expiration time to # `expires` on messages that would # expire before claim. collection.update({ 'p_q': scope, 'e': { '$lt': expires }, 'c.id': cid }, {'$set': { 'e': expires, 't': ttl }}, upsert=False, multi=True)
def delete(self, queue_name, message_id, project=None, claim=None): # NOTE(cpp-cabrera): return early - this is an invalid message # id so we won't be able to find it any way mid = utils.to_oid(message_id) if mid is None: return query = { '_id': mid, 'p': project, 'q': queue_name, } # NOTE(cpp-cabrera): return early - the user gaves us an # invalid claim id and that renders the rest of this # request moot cid = utils.to_oid(claim) if cid is None: return now = timeutils.utcnow_ts() query['e'] = {'$gt': now} message = self._col.find_one(query) if message is None: return is_claimed = (message['c']['id'] is not None and message['c']['e'] > now) if claim is None: if is_claimed: raise exceptions.MessageIsClaimed(message_id) else: if message['c']['id'] != cid: raise exceptions.MessageIsClaimedBy(message_id, claim) self._col.remove(query['_id'], w=0)
def delete(self, queue_name, message_id, project=None, claim=None): # NOTE(cpp-cabrera): return early - this is an invalid message # id so we won't be able to find it any way mid = utils.to_oid(message_id) if mid is None: return collection = self._collection(queue_name, project) query = { '_id': mid, PROJ_QUEUE: utils.scope_queue_name(queue_name, project), } # NOTE(cpp-cabrera): return early - the user gaves us an # invalid claim id and that renders the rest of this # request moot cid = utils.to_oid(claim) if cid is None: return now = timeutils.utcnow_ts() message = collection.find_one(query) if message is None: return is_claimed = (message['c']['id'] is not None and message['c']['e'] > now) if claim is None: if is_claimed: raise errors.MessageIsClaimed(message_id) else: if message['c']['id'] != cid: raise errors.MessageIsClaimedBy(message_id, claim) collection.remove(query['_id'], w=0)
def delete(self, queue_name, message_id, project=None, claim=None): # NOTE(cpp-cabrera): return early - this is an invalid message # id so we won't be able to find it any way mid = utils.to_oid(message_id) if mid is None: return collection = self._collection(queue_name, project) query = { '_id': mid, 'p_q': utils.scope_queue_name(queue_name, project), } # NOTE(cpp-cabrera): return early - the user gaves us an # invalid claim id and that renders the rest of this # request moot cid = utils.to_oid(claim) if cid is None: return now = timeutils.utcnow_ts() message = collection.find_one(query) if message is None: return is_claimed = (message['c']['id'] is not None and message['c']['e'] > now) if claim is None: if is_claimed: raise exceptions.MessageIsClaimed(message_id) else: if message['c']['id'] != cid: raise exceptions.MessageIsClaimedBy(message_id, claim) collection.remove(query['_id'], w=0)
def unclaim(self, queue_name, claim_id, project=None): cid = utils.to_oid(claim_id) # NOTE(cpp-cabrera): early abort - avoid a DB query if we're handling # an invalid ID if cid is None: return # NOTE(cpp-cabrera): unclaim by setting the claim ID to None # and the claim expiration time to now now = timeutils.utcnow_ts() self._col.update({'p': project, 'q': queue_name, 'c.id': cid}, {'$set': {'c': {'id': None, 'e': now}}}, upsert=False, multi=True)
def get(self, queue_name, message_id, project=None): mid = utils.to_oid(message_id) if mid is None: raise errors.MessageDoesNotExist(message_id, queue_name, project) now = timeutils.utcnow_ts() query = {"_id": mid, PROJ_QUEUE: utils.scope_queue_name(queue_name, project)} collection = self._collection(queue_name, project) message = list(collection.find(query).limit(1).hint(ID_INDEX_FIELDS)) if not message: raise errors.MessageDoesNotExist(message_id, queue_name, project) return _basic_message(message[0], now)
def _unclaim(self, queue_name, claim_id, project=None): cid = utils.to_oid(claim_id) # NOTE(cpp-cabrera): early abort - avoid a DB query if we're handling # an invalid ID if cid is None: return # NOTE(cpp-cabrera): unclaim by setting the claim ID to None # and the claim expiration time to now now = timeutils.utcnow_ts() scope = utils.scope_queue_name(queue_name, project) collection = self._collection(queue_name, project) collection.update( {PROJ_QUEUE: scope, "c.id": cid}, {"$set": {"c": {"id": None, "e": now}}}, upsert=False, multi=True )
def get(self, queue_name, message_id, project=None): mid = utils.to_oid(message_id) if mid is None: raise errors.MessageDoesNotExist(message_id, queue_name, project) now = timeutils.utcnow_ts() query = { '_id': mid, PROJ_QUEUE: utils.scope_queue_name(queue_name, project), } collection = self._collection(queue_name, project) message = list(collection.find(query).limit(1).hint(ID_INDEX_FIELDS)) if not message: raise errors.MessageDoesNotExist(message_id, queue_name, project) return _basic_message(message[0], now)
def update(self, queue, claim_id, metadata, project=None): cid = utils.to_oid(claim_id) if cid is None: raise errors.ClaimDoesNotExist(claim_id, queue, project) now = timeutils.utcnow_ts() ttl = int(metadata.get('ttl', 60)) expires = now + ttl msg_ctrl = self.driver.message_controller claimed = msg_ctrl._claimed(queue, cid, expires=now, limit=1, project=project) try: next(claimed) except StopIteration: raise errors.ClaimDoesNotExist(claim_id, queue, project) meta = { 'id': cid, 't': ttl, 'e': expires, } # TODO(kgriffs): Create methods for these so we don't interact # with the messages collection directly (loose coupling) scope = utils.scope_queue_name(queue, project) collection = msg_ctrl._collection(queue, project) collection.update({'p_q': scope, 'c.id': cid}, {'$set': {'c': meta}}, upsert=False, multi=True) # NOTE(flaper87): Dirty hack! # This sets the expiration time to # `expires` on messages that would # expire before claim. collection.update({'p_q': scope, 'e': {'$lt': expires}, 'c.id': cid}, {'$set': {'e': expires, 't': ttl}}, upsert=False, multi=True)
def get(self, queue, claim_id, project=None): msg_ctrl = self.driver.message_controller # Base query, always check expire time now = timeutils.utcnow_ts() cid = utils.to_oid(claim_id) if cid is None: raise errors.ClaimDoesNotExist(queue, project, claim_id) def messages(msg_iter): msg = next(msg_iter) yield msg.pop('claim') yield msg # Smoke it! for msg in msg_iter: del msg['claim'] yield msg try: # Lets get claim's data # from the first message # in the iterator msgs = messages(msg_ctrl._claimed(queue, cid, now, project=project)) claim = next(msgs) update_time = claim['e'] - claim['t'] age = now - update_time claim_meta = { 'age': int(age), 'ttl': claim['t'], 'id': str(claim['id']), } except StopIteration: raise errors.ClaimDoesNotExist(cid, queue, project) return (claim_meta, msgs)
def update(self, queue, claim_id, metadata, project=None): cid = utils.to_oid(claim_id) if cid is None: raise exceptions.ClaimDoesNotExist(claim_id, queue, project) now = timeutils.utcnow_ts() ttl = int(metadata.get('ttl', 60)) expires = now + ttl msg_ctrl = self.driver.message_controller claimed = msg_ctrl.claimed(queue, cid, expires=now, limit=1, project=project) try: next(claimed) except StopIteration: raise exceptions.ClaimDoesNotExist(claim_id, queue, project) meta = { 'id': cid, 't': ttl, 'e': expires, } msg_ctrl._col.update({'q': queue, 'p': project, 'c.id': cid}, {'$set': {'c': meta}}, upsert=False, multi=True) # NOTE(flaper87): Dirty hack! # This sets the expiration time to # `expires` on messages that would # expire before claim. msg_ctrl._col.update({'q': queue, 'p': project, 'e': {'$lt': expires}, 'c.id': cid}, {'$set': {'e': expires, 't': ttl}}, upsert=False, multi=True)