|
@@ -1,17 +1,136 @@
|
|
|
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 lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.BeansException;
|
|
|
+import org.springframework.context.ApplicationContext;
|
|
|
+import org.springframework.context.ApplicationContextAware;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.Map;
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.*;
|
|
|
|
|
|
/**
|
|
|
* @author dyp
|
|
|
*/
|
|
|
@Service
|
|
|
-public class RecallService {
|
|
|
+@Slf4j
|
|
|
+public class RecallService implements ApplicationContextAware {
|
|
|
+
|
|
|
+ private final Map<String, RecallStrategy> strategyMap = new HashMap<>();
|
|
|
+
|
|
|
+ private ApplicationContext applicationContext;
|
|
|
|
|
|
@ApolloJsonValue("city_code")
|
|
|
- private Map<String, String> cityCode;
|
|
|
+ private Set<String> cityCodes;
|
|
|
+
|
|
|
+ private ExecutorService pool;
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ // init thread pool
|
|
|
+ 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()));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ CountDownLatch cdl = new CountDownLatch(strategies.size());
|
|
|
+ List<Future<RecallResult>> recallResultFutures = new ArrayList<>(strategies.size());
|
|
|
+ for (RecallStrategy strategy : strategies) {
|
|
|
+ Future<RecallResult> future = pool.submit(() -> {
|
|
|
+ RecallResult result = strategy.recall(param);
|
|
|
+ cdl.countDown();
|
|
|
+ return result;
|
|
|
+ });
|
|
|
+ recallResultFutures.add(future);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ cdl.await(3000, TimeUnit.MILLISECONDS);
|
|
|
+
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ // 1s 以后返回
|
|
|
+ }
|
|
|
+ // 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
|
|
|
+ }
|
|
|
|
|
|
+ @Override
|
|
|
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
|
|
+ this.applicationContext = applicationContext;
|
|
|
+ }
|
|
|
}
|