def test_fanout_main_task(self): tweet1 = self.create_tweet(user=self.user1) self.create_friendship(from_user=self.user2, to_user=self.user1) msg = fanout_to_followers_main_task(tweet_id=tweet1.id, tweet_user_id=self.user1.id) self.assertEqual(msg, "1 newsfeeds are going to be fanout, " \ "1 batches created, " \ "batch size 3" ) self.assertEqual(1 + 1, NewsFeed.objects.count()) cached_list = NewsFeedService.load_newsfeeds_through_cache( user_id=self.user2.id) self.assertEqual(1, len(cached_list)) # multiple users fanout for i in range(10): user = self.create_user(username='******'.format(i)) self.create_friendship(from_user=user, to_user=self.user1) tweet2 = self.create_tweet(user=self.user1) msg = fanout_to_followers_main_task( tweet_id=tweet2.id, tweet_user_id=self.user1.id, ) self.assertEqual(msg, "11 newsfeeds are going to be fanout, " \ "4 batches created, " \ "batch size 3" ) self.assertEqual(2 + 12, NewsFeed.objects.count()) cached_list = NewsFeedService.load_newsfeeds_through_cache( user_id=self.user2.id) self.assertEqual(2, len(cached_list)) # cache invalidation self.clear_cache() user = self.create_user(username='******') self.create_friendship(from_user=user, to_user=self.user1) tweet3 = self.create_tweet(user=self.user1) msg = fanout_to_followers_main_task( tweet_id=tweet3.id, tweet_user_id=self.user1.id, ) self.assertEqual( msg, "12 newsfeeds are going to be fanout, " \ "4 batches created, " \ "batch size 3" ) self.assertEqual(3 + 24, NewsFeed.objects.count()) cached_list = NewsFeedService.load_newsfeeds_through_cache( user_id=self.user2.id) self.assertEqual(3, len(cached_list))
def list(self, request): cached_newsfeeds = NewsFeedService.load_newsfeeds_through_cache( user_id=request.user.id) page = self.paginator.paginate_cached_list(cached_newsfeeds, request) # cache not enough, access the db directly for extra if not page: newsfeeds = NewsFeed.objects.filter(user_id=request.user.id) page = self.paginate_queryset(newsfeeds) serializer = NewsFeedSerializer( page, context={'request': request}, many=True, ) return self.get_paginated_response(serializer.data)
def test_create_newsfeed_before_get_cached_newsfeeds(self): feed1 = self.create_newsfeed(user=self.user2, tweet=self.create_tweet(user=self.user1)) self.clear_cache() conn = RedisClient.get_connection() name = USER_NEWSFEED_PATTERN.format(user_id=self.user2.id) self.assertFalse(conn.exists(name)) feed2 = self.create_newsfeed(user=self.user2, tweet=self.create_tweet(user=self.user3)) self.assertTrue(conn.exists(name)) feeds = NewsFeedService.load_newsfeeds_through_cache(self.user2.id) self.assertEqual([f.id for f in feeds], [feed2.id, feed1.id])
def test_newsfeed_cache_limit_pagination(self): limit_size = settings.REDIS_LIST_LENGTH_LIMIT page_size = 20 users = [ self.create_user(username='******'.format(i)) for i in range(5) ] newsfeeds = [] for i in range(limit_size + page_size): tweet = self.create_tweet(user=users[i % 5]) feed = self.create_newsfeed(user=self.user2, tweet=tweet) newsfeeds.append(feed) newsfeeds = newsfeeds[::-1] # newsfeed inside and outside cache cached_newsfeeds = NewsFeedService.load_newsfeeds_through_cache( user_id=self.user2.id ) self.assertEqual(len(cached_newsfeeds), limit_size) db_newsfeeds = NewsFeed.objects.filter(user=self.user2) self.assertEqual(len(db_newsfeeds), limit_size+page_size) paginated_newsfeeds = self._paginate_to_get_newsfeeds( client=self.user2_client ) self.assertEqual(len(paginated_newsfeeds), limit_size+page_size) self.assertEqual( [f['id'] for f in paginated_newsfeeds], [f.id for f in newsfeeds] ) # new posts fanout to followers' newsfeeds celebrity, celebrity_client = self.create_user_and_client( username='******' ) self.create_friendship(from_user=self.user2, to_user=celebrity) tweet_celebrity = self.create_tweet(user=celebrity) NewsFeedService.fanout_to_followers(tweet_celebrity) def _test_newsfeeds_after_new_feed_pushed(): db_newsfeeds = NewsFeed.objects.filter(user=self.user2) self.assertEqual(len(db_newsfeeds), limit_size+page_size+1) new_paginated_newsfeed = self._paginate_to_get_newsfeeds( client=self.user2_client ) self.assertEqual( new_paginated_newsfeed[0]['tweet']['id'], tweet_celebrity.id ) for i in range(limit_size+page_size): self.assertEqual( new_paginated_newsfeed[i+1]['id'], newsfeeds[i].id ) _test_newsfeeds_after_new_feed_pushed() # keys expire self.clear_cache() _test_newsfeeds_after_new_feed_pushed()