1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/yeyi771-wxpy

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
wxpyUserService.py 7 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
yeyi Отправлено 07.08.2019 18:03 122387c
# encoding:utf-8
# 封装一些用户保存相关的业务功能
import time, random, threading
from db.wxpyDbAccessFrq import *
from db.wxpyDbUser import *
from wxpyUpload import *
g_updateFriendLock = threading.Lock()
# 启线程更新用户并保存
def updateFriendsThread(bot, dayGap):
# 同一时刻最多一个线程
if not g_updateFriendLock.acquire(False):
logInfo('updateFriendsThrea ing')
return
logInfo('updateFriendsThrea lock start: '+str(g_updateFriendLock))
thread = threading.Thread(target=updateFriends,args=(bot,dayGap))
thread.setDaemon(True)
thread.start()
# 更新数据库中保存的好友信息
# bot: 当前登录用户
# dayGap: 隔多少天更新一次,单位天
def updateFriends(bot, dayGap):
rand = random.randint(5,10)
logInfo('updateFriend sleep : '+str(rand))
time.sleep(rand)
UPDATE_FRIEND_TYPE = 'Bot.friends'
try:
dbd = dbData()
# 获取上次更新好友日期
latestAccess = dbGetAccessFrqLatest(dbd, bot.self.puid, UPDATE_FRIEND_TYPE)
if latestAccess is not None:
logInfo('updateFriend latest: '+str(latestAccess['create_time']))
cut = latestAccess['create_time'].now()-latestAccess['create_time']
if cut.days<dayGap :
logInfo('updateFriend less than dayGap: '+str(cut))
return
# 否则是要更新的
# 取所有好友数据
timeStart = time.perf_counter()
friends = bot.friends(True)
timeEnd = time.perf_counter()
timeSpend = int((time.perf_counter()-timeStart)*1000000000) # 秒乘10的9次方
dbAddAccessFrq(dbd, bot.self, UPDATE_FRIEND_TYPE, timeSpend)
timeStart = time.perf_counter()
for f in friends:
addOrUpdateUser(dbd, f)
timeEnd = time.perf_counter()
logInfo('batch add user spend time: '+str(timeEnd-timeStart))
except Exception as e:
dealException()
logError('updateFriend err: '+str(e))
else:
logInfo('updateFriend success')
finally:
g_updateFriendLock.release()
logInfo('updateFriendsThrea lock release: '+str(g_updateFriendLock))
closeDb(dbd)
# 由于 addOrUpdateUser 调用频率很高,因此为每个 puid 加一个锁
g_addOrUpdateUserRunning = {}
# 锁 g_addOrUpdateUserRunning 用
g_addOrUpdateUserRunningLock = threading.Lock()
# 记录更新当前登录用户最近一次的时间戳(time.perf_counter())
g_curUserUpdateLatest = 0
# 新增或更新用户信息
def addOrUpdateUser(dbd, user):
if user.puid is None:
logError('addOrUpdateUse puid empty: '+str(user))
# 这种情况没有属性,不知道是哪来的
if '<Chat: None>'==str(user):
return
try: # 防止 user.raw 不存在
logError('addOrUpdateUse puid empty2: '+str(user.raw))
except Exception as e:
dealException()
logError('addOrUpdateUse err: '+str(e))
return
# 如果是自己的信息,一天更新一次
global g_curUserUpdateLatest
if isCurUser(user):
curCounter = time.perf_counter()
if curCounter-g_curUserUpdateLatest<1000*60*60*24:
return
logInfo('start update current user, old: '+g_curUserUpdateLatest+' now: '+curCounter)
g_curUserUpdateLatest = curCounter
lock = None
with g_addOrUpdateUserRunningLock:
# 是否已有锁
logInfo('addOrUpdateUse lock in: '+ str(user.puid))
if user.puid in g_addOrUpdateUserRunning.keys():
logInfo('addOrUpdateUse has lock: '+ str(user.puid))
lock = g_addOrUpdateUserRunning[user.puid]
if not lock.acquire(False):
# 拿不到锁证明已经有线程在跑,直接退出
logInfo('addOrUpdateUse locking: '+ str(user.puid))
return
# else: 拿到锁往下走
logInfo('addOrUpdateUse get lock: '+ str(user.puid))
else:
lock = threading.Lock()
lock.acquire()
g_addOrUpdateUserRunning[user.puid] = lock
logInfo('addOrUpdateUse no lock: '+ str(user.puid)+' lockNum: '+str(len(g_addOrUpdateUserRunning)))
logInfo('addOrUpdateUse lock out: '+str(user.puid))
logInfo('addOrUpdateUse lock start: '+str(lock))
dbAddUser(dbd, user)
lock.release()
logInfo('addOrUpdateUse lock release: '+str(lock))
# 把 user_big 及 user 中数据更新到 user_all 中
def updateFromUserBig2UserAll(dbd):
puids = dbGetAllUserDictsByFileName(dbd, 'puid')
if puids is None or len(puids)==0:
logError('updateFromUserBig2UserAl not user data')
return
logInfo('updateFromUserBig2UserAl start:'+id(puids)+'user num: '+len(puids))
timeStart = time.perf_counter()
for puid in puids:
updateFromUserBig2UserPuid(dbd, puid)
timeEnd = time.perf_counter()
logInfo('updateFromUserBig2UserAl end '+id(puids))
logInfo('updateFromUserBig2UserAl spend time: '+str(timeEnd-timeStart))
# 把指定 puid 从 user_big 及 user 中数据更新到 user_all 中
# 返回是否成功
def updateFromUserBig2UserPuid(dbd, puid):
dbUserBig = dbGetUserBig(dbd,puid)
if dbUserBig is None:
logError('updateFromUserBig2UserPui puid empty: '+puid)
return False
try:
# 转成 dict 对象
tUser = json.loads(dbUserBig['raw'])
userBig = camelcase2UnderscoreDictKeys(tUser, getUserRawExceptKeys())
dbUserDict = {}
isgroup = userBig['is_group']
oldUserAll = dbGetUserAll(dbd, puid, isgroup)
if oldUserAll is None:
dbUserDict = userBig
else:
# 若 user_all 中的新,只把 userAll 为默认值的项替换掉
if oldUserAll['update_time']>dbUserBig['update_time']:
for k in oldUserAll.keys():
if hasattr(userBig, k) and isDbUserAllDefaultValue(oldUserAll[k]):
oldUserAll[k] = userBig[k]
logInfo('updateFromUserBig2UserPui1 puid: '+puid+' update key: '+k+' value: '+userBig[k])
# user_big 中的新
else:
for k in oldUserAll.keys():
# userBig 中不是默认值的,都写过来
if hasattr(userBig, k) and (not isDbUserBigDefaultValue(userBig[k])) and hasattr(oldUserAll, k):
oldUserAll[k] = userBig[k]
logInfo('updateFromUserBig2UserPui2 puid: '+puid+' update key: '+k+' value: '+oldUserAll[k])
dbUserDict = oldUserAll
dbuser = dbUser(dbUserDict, puid, isgroup)
return dbAddOrUpdateUserAll(dbd, dbuser)
except Exception as e:
dealException()
logError('updateFromUserBig2UserPui err: '+str(e))
return False

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/yeyi771-wxpy.git
git@api.gitlife.ru:oschina-mirror/yeyi771-wxpy.git
oschina-mirror
yeyi771-wxpy
yeyi771-wxpy
master