|
@@ -1,13 +1,9 @@
|
|
|
package com.tzld.piaoquan.recommend.server.service.recall;
|
|
|
|
|
|
-import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
|
|
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
|
-import com.tzld.piaoquan.recommend.server.service.recall.strategy.Dup224HRegionRecallStrategy;
|
|
|
-import com.tzld.piaoquan.recommend.server.service.recall.strategy.Dup324HRegionRecallStrategy;
|
|
|
-import com.tzld.piaoquan.recommend.server.service.recall.strategy.Region24HRegionRecallStrategy;
|
|
|
-import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionHRegionRecallStrategy;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.springframework.beans.BeansException;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.ApplicationContextAware;
|
|
@@ -25,12 +21,7 @@ import java.util.concurrent.*;
|
|
|
public class RecallService implements ApplicationContextAware {
|
|
|
|
|
|
private final Map<String, RecallStrategy> strategyMap = new HashMap<>();
|
|
|
-
|
|
|
private ApplicationContext applicationContext;
|
|
|
-
|
|
|
- @ApolloJsonValue("city_code")
|
|
|
- private Set<String> cityCodes;
|
|
|
-
|
|
|
private ExecutorService pool;
|
|
|
|
|
|
@PostConstruct
|
|
@@ -39,48 +30,20 @@ public class RecallService implements ApplicationContextAware {
|
|
|
pool = new ThreadPoolExecutor(8, 32,
|
|
|
0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000),
|
|
|
new ThreadFactoryBuilder().setNameFormat("video-title-%d").build(), new ThreadPoolExecutor.AbortPolicy());
|
|
|
-
|
|
|
Map<String, RecallStrategy> type = applicationContext.getBeansOfType(RecallStrategy.class);
|
|
|
for (Map.Entry<String, RecallStrategy> entry : type.entrySet()) {
|
|
|
RecallStrategy value = entry.getValue();
|
|
|
strategyMap.put(value.getClass().getSimpleName(), value);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- public void recall(RecallParam param){
|
|
|
-
|
|
|
- // region recall
|
|
|
- String provinceCode = StringUtils.isNotBlank(param.getProvinceCode())
|
|
|
- ? param.getProvinceCode()
|
|
|
- : "-1";
|
|
|
- String cityCode = StringUtils.isNotBlank(param.getCityCode())
|
|
|
- ? param.getCityCode()
|
|
|
- : "-1";
|
|
|
- String regionCode;
|
|
|
- if (cityCodes.contains(cityCode)) {
|
|
|
- regionCode = cityCode;
|
|
|
- } else {
|
|
|
- regionCode = provinceCode;
|
|
|
- }
|
|
|
-
|
|
|
- List<RecallStrategy> strategies = new ArrayList<>();
|
|
|
- if (regionCode.equals("-1")) {
|
|
|
- strategies.add(strategyMap.get(Dup224HRegionRecallStrategy.class.getSimpleName()));
|
|
|
- strategies.add(strategyMap.get(Dup324HRegionRecallStrategy.class.getSimpleName()));
|
|
|
- } else {
|
|
|
- strategies.add(strategyMap.get(RegionHRegionRecallStrategy.class.getSimpleName()));
|
|
|
- strategies.add(strategyMap.get(Region24HRegionRecallStrategy.class.getSimpleName()));
|
|
|
- strategies.add(strategyMap.get(Dup224HRegionRecallStrategy.class.getSimpleName()));
|
|
|
- strategies.add(strategyMap.get(Dup324HRegionRecallStrategy.class.getSimpleName()));
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ public RecallResult recall(RecallParam param) {
|
|
|
+ List<RecallStrategy> strategies = getRecallStrategy(param);
|
|
|
CountDownLatch cdl = new CountDownLatch(strategies.size());
|
|
|
- List<Future<RecallResult>> recallResultFutures = new ArrayList<>(strategies.size());
|
|
|
+ List<Future<List<RecallResult.RecallData>>> recallResultFutures = new ArrayList<>(strategies.size());
|
|
|
for (RecallStrategy strategy : strategies) {
|
|
|
- Future<RecallResult> future = pool.submit(() -> {
|
|
|
- RecallResult result = strategy.recall(param);
|
|
|
+ Future<List<RecallResult.RecallData>> future = pool.submit(() -> {
|
|
|
+ List<RecallResult.RecallData> result = strategy.recall(param);
|
|
|
cdl.countDown();
|
|
|
return result;
|
|
|
});
|
|
@@ -88,45 +51,135 @@ public class RecallService implements ApplicationContextAware {
|
|
|
}
|
|
|
try {
|
|
|
cdl.await(3000, TimeUnit.MILLISECONDS);
|
|
|
-
|
|
|
} catch (InterruptedException e) {
|
|
|
- // 1s 以后返回
|
|
|
+ log.error("rov_pool_recall_with_region recall error", e);
|
|
|
+ return null;
|
|
|
}
|
|
|
- // region_recall_result_list = [i.get() for i in t]
|
|
|
- // # 将已获取到的视频按顺序去重合并
|
|
|
- // now_video_ids = []
|
|
|
- // recall_result = []
|
|
|
- // recall_num = size
|
|
|
- // for region_result in region_recall_result_list:
|
|
|
- // for video in region_result:
|
|
|
- // video_id = video.get('videoId')
|
|
|
- // if video_id not in now_video_ids:
|
|
|
- // recall_result.append(video)
|
|
|
- // now_video_ids.append(video_id)
|
|
|
- // if len(recall_result) >= recall_num:
|
|
|
- // break
|
|
|
- // else:
|
|
|
- // continue
|
|
|
- // return recall_result[:recall_num]
|
|
|
-
|
|
|
-
|
|
|
- // # 对在流量池中存在的视频添加标记字段
|
|
|
- // result = []
|
|
|
- // for item in videos:
|
|
|
- // video_id = item['videoId']
|
|
|
- // t = [
|
|
|
- // gevent.spawn(self.get_video_flow_pool, video_id, True),
|
|
|
- // gevent.spawn(self.get_video_flow_pool, video_id, False)
|
|
|
- // ]
|
|
|
- // gevent.joinall(t)
|
|
|
- // flow_pool_list = [i.get() for i in t]
|
|
|
- // flow_pool_list = [item for item in flow_pool_list if item != '']
|
|
|
- // if len(flow_pool_list) > 0:
|
|
|
- // flow_pool = flow_pool_list[0]
|
|
|
- // item['flowPool'] = flow_pool
|
|
|
- // item['isInFlowPool'] = 1
|
|
|
- // result.append(item)
|
|
|
- // return result
|
|
|
+
|
|
|
+
|
|
|
+ // TODO 重构
|
|
|
+ // merge
|
|
|
+ return merge(recallResultFutures, param);
|
|
|
+ }
|
|
|
+
|
|
|
+ private RecallResult merge(List<Future<List<RecallResult.RecallData>>> recallResultFutures, RecallParam param) {
|
|
|
+ List<List<RecallResult.RecallData>> results = new ArrayList<>();
|
|
|
+ for (Future<List<RecallResult.RecallData>> f : recallResultFutures) {
|
|
|
+ try {
|
|
|
+ results.add(f.get());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("future get error ", e);
|
|
|
+ results.add(Collections.emptyList());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO 重构 merge sim recall and return recall
|
|
|
+ Set<Long> videoIds = new HashSet<>();
|
|
|
+ List<RecallResult.RecallData> datas = new ArrayList<>();
|
|
|
+ if (param.getAbCode().equals("60054")
|
|
|
+ || param.getAbCode().equals("60068")
|
|
|
+ || param.getAbCode().equals("60081")
|
|
|
+ || param.getAbCode().equals("60084")) {
|
|
|
+ if (results.size() >= 2) {
|
|
|
+ List<RecallResult.RecallData> region_recall = results.get(0);
|
|
|
+ if (CollectionUtils.isNotEmpty(region_recall)) {
|
|
|
+ for (RecallResult.RecallData data : region_recall) {
|
|
|
+ if (!videoIds.contains(data.getVideoId())) {
|
|
|
+ datas.add(data);
|
|
|
+ videoIds.add(data.getVideoId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<RecallResult.RecallData> simRecall = null;
|
|
|
+ List<RecallResult.RecallData> returnRecall = null;
|
|
|
+ if (param.getAppType().equals("18") || param.getAppType().equals("19")) {
|
|
|
+ simRecall = results.get(1);
|
|
|
+ } else {
|
|
|
+ if (results.size() >= 4) {
|
|
|
+ simRecall = results.get(3);
|
|
|
+ }
|
|
|
+ if (results.size() >= 5 && !param.getAbCode().equals("60054")) {
|
|
|
+ returnRecall = results.get(4);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (simRecall != null && CollectionUtils.isNotEmpty(simRecall)) {
|
|
|
+ for (RecallResult.RecallData data : simRecall) {
|
|
|
+ if (!videoIds.contains(data.getVideoId())) {
|
|
|
+ datas.add(data);
|
|
|
+ videoIds.add(data.getVideoId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (returnRecall != null && CollectionUtils.isNotEmpty(returnRecall)) {
|
|
|
+ for (RecallResult.RecallData data : returnRecall) {
|
|
|
+ if (!videoIds.contains(data.getVideoId())) {
|
|
|
+ datas.add(data);
|
|
|
+ videoIds.add(data.getVideoId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(datas)) {
|
|
|
+ results.set(0, datas);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ RecallResult result = new RecallResult();
|
|
|
+ if (param.getAppType().equals("18") || param.getAppType().equals("19")) {
|
|
|
+ // TODO 可能没有这个code
|
|
|
+ if (param.getAbCode().equals("30001")
|
|
|
+ || param.getAbCode().equals("30002")
|
|
|
+ || param.getAbCode().equals("80001")) {
|
|
|
+ result.setRovPoolRecall(results.get(0));
|
|
|
+ result.setFlowPoolRecall(results.get(1));
|
|
|
+ } else {
|
|
|
+ result.setRovPoolRecall(results.get(0));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (CollectionUtils.isNotEmpty(results.get(1))) {
|
|
|
+ result.setQuickPool(true);
|
|
|
+ result.setRovPoolRecall(results.get(0));
|
|
|
+ result.setFlowPoolRecall(results.get(1));
|
|
|
+
|
|
|
+ } else {
|
|
|
+ result.setRovPoolRecall(results.get(0));
|
|
|
+ result.setFlowPoolRecall(results.get(2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<RecallStrategy> getRecallStrategy(RecallParam param) {
|
|
|
+ List<RecallStrategy> strategies = new ArrayList<>();
|
|
|
+ if (param.getAppType().equals("18") || param.getAppType().equals("19")) {
|
|
|
+ strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
|
|
|
+ } else if (param.getFlowPoolAbtestGroup().equals("experimental_flow_set_level")) {
|
|
|
+ strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(QuickFlowPoolWithLevelRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(FlowPoolWithLevelRecallStrategy.class.getSimpleName()));
|
|
|
+ } else if (param.getFlowPoolAbtestGroup().equals("experimental_flow_set_level_score")) {
|
|
|
+ strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(QuickFlowPoolWithLevelScoreRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(FlowPoolWithLevelScoreRecallStrategy.class.getSimpleName()));
|
|
|
+ } else {
|
|
|
+ strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(QuickFlowPoolWithScoreRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(FlowPoolWithScoreRecallStrategy.class.getSimpleName()));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (param.getAbCode().equals("60054")) {
|
|
|
+ strategies.add(strategyMap.get(SimHotVideoRecallStrategy.class.getSimpleName()));
|
|
|
+ } else if (param.getAbCode().equals("60068")
|
|
|
+ || param.getAbCode().equals("60081")
|
|
|
+ || param.getAbCode().equals("60084")) {
|
|
|
+ strategies.add(strategyMap.get(SimHotVideoRecallStrategy.class.getSimpleName()));
|
|
|
+ strategies.add(strategyMap.get(ReturnVideoRecallStrategy.class.getSimpleName()));
|
|
|
+ }
|
|
|
+
|
|
|
+ return strategies;
|
|
|
}
|
|
|
|
|
|
@Override
|