def create(self, queue, subscriber, ttl, options, project=None): member_key = utils.scope_subscribers_set(queue, project, SUBSCRIBERS_SUFFIX) if self._client.sismember(member_key, subscriber): return None subscription_id = str(uuid.uuid4()) subset_key = utils.scope_subscription_ids_set(queue, project, SUBSCRIPTION_IDS_SUFFIX) source = queue now = timeutils.utcnow_ts() ttl = int(ttl) expires = now + ttl subscription = {'id': subscription_id, 's': source, 'u': subscriber, 't': ttl, 'e': expires, 'o': self._packer(options), 'p': project} if not self._queue_ctrl.exists(queue, project): raise errors.QueueDoesNotExist(queue, project) try: # Pipeline ensures atomic inserts. with self._client.pipeline() as pipe: pipe.sadd(member_key, subscriber) pipe.zadd(subset_key, 1, subscription_id).hmset(subscription_id, subscription) pipe.execute() return subscription_id except redis.exceptions.ResponseError: return None
def delete(self, queue, subscription_id, project=None): subset_key = utils.scope_subscription_ids_set(queue, project, SUBSCRIPTION_IDS_SUFFIX) member_key = utils.scope_subscribers_set(queue, project, SUBSCRIBERS_SUFFIX) subscriber = self._client.hget(subscription_id, 'u') # NOTE(prashanthr_): Pipelining is used to mitigate race conditions with self._client.pipeline() as pipe: pipe.srem(member_key, subscriber) pipe.zrem(subset_key, subscription_id) pipe.delete(subscription_id) pipe.execute()
def create(self, queue, subscriber, ttl, options, project=None): member_key = utils.scope_subscribers_set(queue, project, SUBSCRIBERS_SUFFIX) if self._client.sismember(member_key, subscriber): return None subscription_id = str(uuid.uuid4()) subset_key = utils.scope_subscription_ids_set(queue, project, SUBSCRIPTION_IDS_SUFFIX) source = queue now = timeutils.utcnow_ts() ttl = int(ttl) expires = now + ttl subscription = { 'id': subscription_id, 's': source, 'u': subscriber, 't': ttl, 'e': expires, 'o': self._packer(options), 'p': project } if not self._queue_ctrl.exists(queue, project): raise errors.QueueDoesNotExist(queue, project) try: # Pipeline ensures atomic inserts. with self._client.pipeline() as pipe: pipe.sadd(member_key, subscriber) pipe.zadd(subset_key, 1, subscription_id).hmset(subscription_id, subscription) pipe.execute() return subscription_id except redis.exceptions.ResponseError: return None