| 
					
				 | 
			
			
				@@ -0,0 +1,141 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package com.tzld.piaoquan.recommend.server.service.score; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.recommend.feature.domain.video.base.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.recommend.feature.domain.video.base.UserFeature; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.recommend.server.common.base.RankItem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.recommend.server.service.score.model.ThompsonSamplingModel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.collections4.CollectionUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.lang.exception.ExceptionUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.slf4j.Logger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.slf4j.LoggerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.ArrayList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.concurrent.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//@Service 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class VlogThompsonScorer extends BaseThompsonSamplingScorer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final int LOCAL_TIME_OUT = 150; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private final static Logger LOGGER = LoggerFactory.getLogger(VlogThompsonScorer.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final ExecutorService executorService = Executors.newFixedThreadPool(128); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public VlogThompsonScorer(ScorerConfigInfo configInfo) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        super(configInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public List<RankItem> scoring(final ScoreParam param, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  final UserFeature userFeature, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  final List<RankItem> rankItems) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (userFeature == null || CollectionUtils.isEmpty(rankItems)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return rankItems; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        long startTime = System.currentTimeMillis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ThompsonSamplingModel model = (ThompsonSamplingModel) this.getModel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LOGGER.debug("model size: [{}]", model.getModelSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<RankItem> result = rankItems; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result = rankByJava(rankItems, param.getRequestContext(), userFeature); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LOGGER.debug("thompson sampling ctr ranker time java items size={}, time={} ", result != null ? result.size() : 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                System.currentTimeMillis() - startTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private List<RankItem> rankByJava(final List<RankItem> items, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      final RequestContext requestContext, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      final UserFeature user) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        long startTime = System.currentTimeMillis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ThompsonSamplingModel model = (ThompsonSamplingModel) this.getModel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LOGGER.debug("model size: [{}]", model.getModelSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 所有都参与打分,按照ROV Thompson排序 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        multipleCtrScore(items, model); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // debug log 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (LOGGER.isDebugEnabled()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 0; i < items.size(); i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                LOGGER.debug("after enter feeds model predict ctr score [{}] [{}]", items.get(i), items.get(i).getScore()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LOGGER.debug("thompson ranker java execute time: [{}]", System.currentTimeMillis() - startTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LOGGER.debug("[thompson ranker time java] items size={}, cost={} ", items != null ? items.size() : 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                System.currentTimeMillis() - startTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return items; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 计算 predict ROV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public double calcScore(final ThompsonSamplingModel model, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            final RankItem item) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        double score = 0d; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            score = model.score(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            LOGGER.error("score error for doc={} exception={}", new Object[]{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    item.getVideo(), ExceptionUtils.getFullStackTrace(e)}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        item.setScore(score); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return score; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 并行打分 Thompson ROV 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param items 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param model 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void multipleCtrScore(final List<RankItem> items, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  final ThompsonSamplingModel model) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Callable<Object>> calls = new ArrayList<Callable<Object>>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int index = 0; index < items.size(); index++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            final int fIndex = index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            items.get(fIndex).setScore(0.0);   //设置为原始值为0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            calls.add(new Callable<Object>() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                public Object call() throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        calcScore(model, items.get(fIndex)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        LOGGER.error("thompson exception: [{}] [{}]", items.get(fIndex).videoId, ExceptionUtils.getFullStackTrace(e)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return new Object(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Future<Object>> futures = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            futures = executorService.invokeAll(calls, LOCAL_TIME_OUT, TimeUnit.MILLISECONDS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (InterruptedException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            LOGGER.error("execute invoke fail: {}", ExceptionUtils.getFullStackTrace(e)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //等待所有请求的结果返回, 超时也返回 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int cancel = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (futures != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (Future<Object> future : futures) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!future.isDone() || future.isCancelled() || future.get() == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        cancel++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } catch (InterruptedException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    LOGGER.error("InterruptedException {},{}", ExceptionUtils.getFullStackTrace(e)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } catch (ExecutionException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    LOGGER.error("ExecutionException {},{}", ExceptionUtils.getFullStackTrace(e)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LOGGER.debug("ROV-Thompson Score {}, Total: {}, Cancel: {}", new Object[]{items.size(), cancel}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |