RK_NOTIFICATIONS_COUNTER = 'ss_pending_counter_changes'
def update_unread_count(self, count):
"""修改过的update_unread_count方法"""
redisdb.zincrby(RK_NOTIFICATIONS_COUNTER, str(self.user_id), count)
# 同时我们也需要修改获取用户未读消息数方法,使其获取redis中那些没有被回写
# 到数据库的缓冲区数据。在这里代码就省略了
通过以上的代码,我们把计数器的更新缓冲在了redis里面,我们还需要一个脚本来把这个缓冲区 里面的数据定时回写到数据库中。
通过自定义django的command,我们可以非常轻松的做到这一点:
# File: management/commands/notification_update_counter.py
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand
from django.db.models import F
# Fix import prob
from notification.models import UserNotificationsCount
from notification.utils import RK_NOTIFICATIONS_COUNTER
from base_redis import redisdb
import logging
logger = logging.getLogger('stdout')
class Command(BaseCommand):
help = 'Update UserNotificationsCounter objects, Write changes from redis to database'
def handle(self, *args, **options):
# 首先,通过 zrange 命令来获取缓冲区所有修改过的用户ID
for user_id in redisdb.zrange(RK_NOTIFICATIONS_COUNTER, 0, -1):
# 这里值得注意,为了保证操作的原子性,我们使用了redisdb的pipeline
pipe = redisdb.pipeline()
pipe.zscore(RK_NOTIFICATIONS_COUNTER, user_id)
pipe.zrem(RK_NOTIFICATIONS_COUNTER, user_id)
count, _ = pipe.execute()
count = int(count)
if not count:
continue
logger.info('Updating unread count user %s: count %s' % (user_id, count))
UserNotificationsCount.objects.filter(pk=obj.pk)
.update(unread_count=F('unread_count') + count)










