|
@@ -2,9 +2,9 @@ import time
|
|
|
|
|
|
from datetime import date, timedelta, datetime
|
|
|
from log import Log
|
|
|
-from db_helper import RedisHelper
|
|
|
from config import set_config
|
|
|
from utils import FilterVideos, get_videos_remain_view_count, get_videos_local_distribute_count
|
|
|
+import aiocache
|
|
|
|
|
|
log_ = Log()
|
|
|
config_ = set_config()
|
|
@@ -24,13 +24,12 @@ class PoolRecall(object):
|
|
|
self.mid = mid
|
|
|
self.uid = uid
|
|
|
self.ab_code = ab_code
|
|
|
- self.redis_helper = RedisHelper()
|
|
|
|
|
|
- def rov_pool_recall(self, size=10):
|
|
|
+ async def rov_pool_recall(self, size=10):
|
|
|
"""从ROV召回池中获取视频"""
|
|
|
log_.info('====== rov pool recall')
|
|
|
# 获取相关redis key, 用户上一次在rov召回池对应的位置
|
|
|
- rov_pool_key, last_rov_recall_key, idx = self.get_video_last_idx()
|
|
|
+ rov_pool_key, last_rov_recall_key, idx = await self.get_video_last_idx()
|
|
|
if not rov_pool_key:
|
|
|
log_.info('ROV召回池中无视频')
|
|
|
return []
|
|
@@ -45,7 +44,7 @@ class PoolRecall(object):
|
|
|
break
|
|
|
# 获取数据
|
|
|
st_get = time.time()
|
|
|
- data = self.redis_helper.get_data_zset_with_index(key_name=rov_pool_key,
|
|
|
+ data = await aiocache.get_data_zset_with_index(key_name=rov_pool_key,
|
|
|
start=idx, end=idx + get_size - 1,
|
|
|
with_scores=True)
|
|
|
et_get = time.time()
|
|
@@ -62,7 +61,7 @@ class PoolRecall(object):
|
|
|
video_score[eval(value[0])] = value[1]
|
|
|
# 过滤
|
|
|
filter_ = FilterVideos(app_type=self.app_type, mid=self.mid, uid=self.uid, video_ids=video_ids)
|
|
|
- filtered_result = filter_.filter_videos()
|
|
|
+ filtered_result = await filter_.filter_videos()
|
|
|
if filtered_result:
|
|
|
# 添加视频源参数 pushFrom, abCode
|
|
|
temp_result = [{'videoId': item, 'rovScore': video_score[item],
|
|
@@ -71,14 +70,14 @@ class PoolRecall(object):
|
|
|
rov_pool_recall_result.extend(temp_result)
|
|
|
else:
|
|
|
# 将此次获取的末位视频id同步刷新到Redis中,方便下次快速定位到召回位置,过期时间为1天
|
|
|
- self.redis_helper.set_data_to_redis(key_name=last_rov_recall_key, value=data[-1][0])
|
|
|
+ await aiocache.set_data_to_redis(key_name=last_rov_recall_key, value=data[-1][0])
|
|
|
idx += get_size
|
|
|
return rov_pool_recall_result[:size]
|
|
|
|
|
|
- def flow_pool_recall(self, size=10):
|
|
|
+ async def flow_pool_recall(self, size=10):
|
|
|
"""从流量池中获取视频"""
|
|
|
log_.info('====== flow pool recall')
|
|
|
- flow_pool_key = self.get_pool_redis_key('flow')
|
|
|
+ flow_pool_key = await self.get_pool_redis_key('flow')
|
|
|
flow_pool_recall_result = []
|
|
|
flow_pool_recall_videos = []
|
|
|
# 每次获取的视频数
|
|
@@ -90,7 +89,7 @@ class PoolRecall(object):
|
|
|
freq += 1
|
|
|
# 获取数据
|
|
|
st_get = time.time()
|
|
|
- data = self.redis_helper.get_data_zset_with_index(key_name=flow_pool_key,
|
|
|
+ data = await aiocache.get_data_zset_with_index(key_name=flow_pool_key,
|
|
|
start=idx, end=idx + get_size - 1,
|
|
|
with_scores=True)
|
|
|
et_get = time.time()
|
|
@@ -104,7 +103,8 @@ class PoolRecall(object):
|
|
|
video_mapping = {}
|
|
|
video_score = {}
|
|
|
for value in data:
|
|
|
- video_id, flow_pool = value[0].split('-')
|
|
|
+ value0 = str(value[0], 'utf-8')
|
|
|
+ video_id, flow_pool = value0.split('-')
|
|
|
video_id = eval(video_id)
|
|
|
if video_id not in video_ids:
|
|
|
video_ids.append(video_id)
|
|
@@ -115,11 +115,11 @@ class PoolRecall(object):
|
|
|
video_mapping[video_id].append(flow_pool)
|
|
|
# 过滤
|
|
|
filter_ = FilterVideos(app_type=self.app_type, mid=self.mid, uid=self.uid, video_ids=video_ids)
|
|
|
- filtered_result = filter_.filter_videos()
|
|
|
+ filtered_result = await filter_.filter_videos()
|
|
|
# 检查可分发数
|
|
|
if filtered_result:
|
|
|
st_check = time.time()
|
|
|
- check_result = self.check_video_counts(video_ids=filtered_result, flow_pool_mapping=video_mapping)
|
|
|
+ check_result = await self.check_video_counts(video_ids=filtered_result, flow_pool_mapping=video_mapping)
|
|
|
for item in check_result:
|
|
|
if item[0] not in flow_pool_recall_videos:
|
|
|
# 取其中一个 flow_pool 作为召回结果
|
|
@@ -136,22 +136,22 @@ class PoolRecall(object):
|
|
|
|
|
|
return flow_pool_recall_result[:size]
|
|
|
|
|
|
- def check_video_counts(self, video_ids, flow_pool_mapping):
|
|
|
+ async def check_video_counts(self, video_ids, flow_pool_mapping):
|
|
|
"""
|
|
|
检查视频剩余可分发数
|
|
|
:param video_ids: 视频id type-list
|
|
|
:param flow_pool_mapping: 视频id-流量池标记mapping, type-dict
|
|
|
:return:
|
|
|
"""
|
|
|
- flow_pool_key = self.get_pool_redis_key('flow')
|
|
|
+ flow_pool_key = await self.get_pool_redis_key('flow')
|
|
|
videos = []
|
|
|
for video_id in video_ids:
|
|
|
for flow_pool in flow_pool_mapping[video_id]:
|
|
|
videos.append({'videoId': video_id, 'flowPool': flow_pool})
|
|
|
- view_count_result = get_videos_remain_view_count(app_type=self.app_type, videos=videos)
|
|
|
+ view_count_result = await get_videos_remain_view_count(app_type=self.app_type, videos=videos)
|
|
|
log_.info('view_count_result = {}'.format(view_count_result))
|
|
|
if not view_count_result:
|
|
|
- return None
|
|
|
+ return []
|
|
|
check_result = []
|
|
|
for item in view_count_result:
|
|
|
if item[2] > 0:
|
|
@@ -163,15 +163,15 @@ class PoolRecall(object):
|
|
|
# cur_count <= 0,从流量召回池移除
|
|
|
else:
|
|
|
value = '{}-{}'.format(item[0], item[1])
|
|
|
- self.redis_helper.remove_value_from_zset(key_name=flow_pool_key, value=value)
|
|
|
+ await aiocache.remove_value_from_zset(key_name=flow_pool_key, value=value)
|
|
|
else:
|
|
|
# viewCount <= 0
|
|
|
# 从流量召回池移除
|
|
|
value = '{}-{}'.format(item[0], item[1])
|
|
|
- self.redis_helper.remove_value_from_zset(key_name=flow_pool_key, value=value)
|
|
|
+ await aiocache.remove_value_from_zset(key_name=flow_pool_key, value=value)
|
|
|
return check_result
|
|
|
|
|
|
- def get_pool_redis_key(self, pool_type):
|
|
|
+ async def get_pool_redis_key(self, pool_type):
|
|
|
"""
|
|
|
拼接key
|
|
|
:param pool_type: type-string {'rov': rov召回池, 'flow': 流量池}
|
|
@@ -184,7 +184,7 @@ class PoolRecall(object):
|
|
|
redis_date = datetime.now().hour
|
|
|
# 判断热度列表是否更新,未更新则使用前一小时的热度列表
|
|
|
key_name = '{}{}.{}'.format(config_.RECALL_KEY_NAME_PREFIX_APP_TYPE, self.app_type, redis_date)
|
|
|
- if self.redis_helper.key_exists(key_name):
|
|
|
+ if await aiocache.key_exists(key_name):
|
|
|
return key_name, redis_date
|
|
|
else:
|
|
|
key_name = '{}{}.{}'.format(config_.RECALL_KEY_NAME_PREFIX_APP_TYPE, self.app_type, redis_date - 1)
|
|
@@ -193,7 +193,7 @@ class PoolRecall(object):
|
|
|
else:
|
|
|
# 判断热度列表是否更新,未更新则使用前一天的热度列表
|
|
|
key_name = config_.RECALL_KEY_NAME_PREFIX + time.strftime('%Y%m%d')
|
|
|
- if self.redis_helper.key_exists(key_name):
|
|
|
+ if await aiocache.key_exists(key_name):
|
|
|
redis_date = date.today().strftime('%Y%m%d')
|
|
|
else:
|
|
|
redis_date = (date.today() - timedelta(days=1)).strftime('%Y%m%d')
|
|
@@ -209,16 +209,16 @@ class PoolRecall(object):
|
|
|
log_.error('pool type error')
|
|
|
return None, None
|
|
|
|
|
|
- def get_video_last_idx(self):
|
|
|
+ async def get_video_last_idx(self):
|
|
|
"""获取用户上一次在rov召回池对应的位置"""
|
|
|
- rov_pool_key, redis_date = self.get_pool_redis_key('rov')
|
|
|
+ rov_pool_key, redis_date = await self.get_pool_redis_key('rov')
|
|
|
if not rov_pool_key:
|
|
|
return None, None, None
|
|
|
last_rov_recall_key = config_.LAST_VIDEO_FROM_ROV_POOL_PREFIX + '{}.{}.{}'.format(
|
|
|
self.app_type, self.mid, redis_date)
|
|
|
- value = self.redis_helper.get_data_from_redis(last_rov_recall_key)
|
|
|
+ value = await aiocache.get_data_from_redis(last_rov_recall_key)
|
|
|
if value:
|
|
|
- idx = self.redis_helper.get_index_with_data(rov_pool_key, value)
|
|
|
+ idx = await aiocache.get_index_with_data(rov_pool_key, value)
|
|
|
if not idx:
|
|
|
idx = 0
|
|
|
else:
|