def _recreate_user_timeline(self, consumer_id): """ for when (server restarts, or a new user logs in) :return: True on success """ content = (self._relations.select( self._dataset.item_id, self._dataset.timestamp).join( self._dataset, on=(self._relations.producer_id == self._dataset.producer_id )).where( self._relations.consumer_id == consumer_id).order_by( self._dataset.timestamp.desc()).limit( self._max_cache).namedtuples()) consumer_feed = self.create_cache_name(consumer_id) for chunk in chunked(content, 400): redis.zadd(consumer_feed, dict((c.item_id, c.timestamp) for c in chunk)) if not self._include_actor: return True content = (self._dataset.select( self._dataset.item_id, self._dataset.timestamp).where( self._dataset.producer_id == consumer_id)) pipe = redis.pipeline() for chunk in chunked(content, 400): pipe.zadd(consumer_id, dict( (c.item_id, c.timestamp) for c in chunk)) pipe.execute() return True
def _publish_fan_out_from_producer(self, producer_id, item_id): """ for when a consumer publishes new content :return: True on success """ # get producer's followers followers = (self._relations.select(self._relations.consumer_id).where( self._relations.producer_id == producer_id).namedtuples()) content = self._dataset.get(self._dataset.item_id == item_id) content_info = {content.item_id: content.timestamp} # inject content id to their list pipe = redis.pipeline() for follower in followers: pipe.zadd(self.create_cache_name(follower.consumer_id), content_info) pipe.eval(self.clean_excess_from_cache(follower.consumer_id), 0) if self._include_actor: pipe.zadd(self.create_cache_name(producer_id), content_info) pipe.eval(self.clean_excess_from_cache(producer_id), 0) pipe.execute() return True
def _delete_fan_out_from_producer(self, producer_id, item_id): """ for when a producer retracts their content :return: True on success """ # get producer's followers followers = (self._relations.select(self._relations.consumer_id).where( self._relations.producer_id == producer_id).namedtuples()) # inject content id to their list pipe = redis.pipeline() for follower in followers: pipe.zrem(self.create_cache_name(follower.consumer_id), item_id) if self._include_actor: pipe.zrem(self.create_cache_name(producer_id), item_id) pipe.execute() return True
def _add_from_producer_to_consumer(self, producer_id, consumer_id): """ for subscribe events. :return: True on success """ # get producer's content content = (self._dataset.select( self._dataset.item_id, self._dataset.timestamp).where( (self._dataset.producer_id == producer_id))) pipe = redis.pipeline() consumer_feed = self.create_cache_name(consumer_id) for chunk in chunked(content, 400): pipe.zadd(consumer_feed, dict((c.item_id, c.timestamp) for c in chunk)) pipe.eval(self.clean_excess_from_cache(consumer_id), 0) pipe.execute() return True
def _delete_from_producer_for_consumer(self, producer_id, consumer_id): """ for unsubscribe events. :param producer_id: producer's id :param consumer_id: consumer's id :return: True on success """ # get producer's recent content (need to figure out how many) content_ids = (self._dataset.select(self._dataset.item_id).where( (self._dataset.producer_id == producer_id)).namedtuples()) # inject to consumer's feed list pipe = redis.pipeline() consumer_feed = self.create_cache_name(consumer_id) for content_id in content_ids: pipe.zrem(consumer_feed, content_id.item_id) pipe.execute() return True
def _delete_from_producer_for_consumer(self, consumer_id, producer_id): """ for unsubscribe :param consumer_id: consumer's id :param producer_id: producer's id :return: True on success """ # get items from producer for consumer content_ids = list( self._dataset.select(self._dataset.item_id).where( (self._dataset.producer_id == producer_id) & (self._dataset.consumer_id == consumer_id)).dicts()) pipe = redis.pipeline() consumer_feed = self.create_cache_name(consumer_id) for content_id in content_ids: pipe.zrem(consumer_feed, content_id['item_id']) pipe.execute() return True
def _recreate_user_timeline(self, consumer_id): """ recreate users timeline :param consumer_id: consumer's id :return: True on success """ # get all content with consumer_id as target content = (self._dataset.select( self._dataset.item_id, self._dataset.timestamp).where( self._dataset.consumer_id == consumer_id).order_by( self._dataset.timestamp.desc()).limit(self._max_cache)) pipe = redis.pipeline() consumer_feed = self.create_cache_name(consumer_id) for chunk in chunked(content, 400): pipe.zadd(consumer_feed, dict((c.item_id, c.timestamp) for c in chunk)) pipe.execute() return True