Pārlūkot izejas kodu

async translation

fengchang_fight 1 gadu atpakaļ
vecāks
revīzija
1d2ddca092

+ 16 - 0
hichina-main-back/src/main/java/com/hichina/main/back/hichinamainback/HichinaMainBackApplication.java

@@ -2,12 +2,28 @@ package com.hichina.main.back.hichinamainback;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
 
 @SpringBootApplication
+@EnableAsync
 public class HichinaMainBackApplication {
 
 	public static void main(String[] args) {
 		SpringApplication.run(HichinaMainBackApplication.class, args);
 	}
 
+	@Bean
+	public Executor taskExecutor() {
+		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+		executor.setCorePoolSize(8);
+		executor.setMaxPoolSize(8);
+		executor.setQueueCapacity(500);
+		executor.setThreadNamePrefix("HichinaThread-");
+		executor.initialize();
+		return executor;
+	}
 }

+ 22 - 48
hichina-main-back/src/main/java/com/hichina/main/back/hichinamainback/controller/BaiduTranslateController.java

@@ -1,18 +1,10 @@
 package com.hichina.main.back.hichinamainback.controller;
 
 import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
 import com.hichina.main.back.hichinamainback.model.DTO.BaiduTranslateRequestDTO;
 import com.hichina.main.back.hichinamainback.model.DTO.HichinaResponse;
-import com.hichina.main.back.hichinamainback.model.DTO.TranslateObj;
-import com.hichina.main.back.hichinamainback.repository.BaiduTranslateCacheRepository;
 import com.hichina.main.back.hichinamainback.service.BaiduTranslateApiService;
-import org.apache.commons.lang3.StringUtils;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Node;
-import org.jsoup.nodes.TextNode;
+import com.hichina.main.back.hichinamainback.utils.RedisUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,7 +13,6 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.List;
 
 @RestController
 @RequestMapping("/api/public/baidutranslate")
@@ -32,6 +23,8 @@ public class BaiduTranslateController {
     private BaiduTranslateApiService baiduTranslateApiService;
 
 
+    @Autowired
+    private RedisUtil redisUtil;
 
     private static Gson gson = new Gson();
 
@@ -39,52 +32,33 @@ public class BaiduTranslateController {
     public HichinaResponse baiduTranslate(@RequestBody BaiduTranslateRequestDTO request){
         HichinaResponse ret = new HichinaResponse();
 
+        // check if translation job is ongoing, if it is return and notify user, else continue with reading cache or trigger translation job
+
+        if(redisUtil.get(request.getTranslationKey())!=null){
+            ret.setMessage("A translation job is ongoing...");
+            ret.setOk(false);
+            return ret;
+        }
+
         String translatedText = "";
 
         String cachedText = baiduTranslateApiService.fetchTranslationValueByKey(request.getTranslationKey());
         if(cachedText!=null){
             translatedText = cachedText;
+            ret.setOk(true);
+            ret.setMessage("Succeed getting baidu translation");
+            ret.setData(translatedText);
+            return ret;
         }else{
-            Document doc = Jsoup.parse(request.getQuery());
-            htmlTextTagsTranslate(doc.childNodes(), request.getFrom(), request.getTo());
-            translatedText = doc.html();
-            baiduTranslateApiService.cacheTranslation(request.getTranslationKey(), translatedText);
+            // 1. add redis cache indicating a translation job is submitted
+            redisUtil.add(request.getTranslationKey(), 5*60L, "");
+            // 2. start an async job doing the translation and return with notify message imediately
+            baiduTranslateApiService.triggerTranslationJobAsync(request.getTranslationKey(), request.getQuery(), request.getFrom(), request.getTo());
+            ret.setOk(true);
+            ret.setMessage("Triggered a job translating this blog");
+            return ret;
         }
-        ret.setOk(true);
-        ret.setMessage("Succeed getting baidu translation");
-        ret.setData(translatedText);
-        return ret;
     }
 
-    private void htmlTextTagsTranslate(List<Node> nodes, String from, String to) {
-        for(Node node:nodes) {
-            htmlTextTagsTranslate(node.childNodes(), from, to);
-            if(node instanceof TextNode){
-                String originalText = ((TextNode) node).text();
 
-                if(StringUtils.isEmpty(originalText.trim())){
-                    LOG.info("==============empty text node skip========");
-                    continue;
-                }
-                JsonObject result = baiduTranslateApiService.getTransResult(originalText, from, to);
-                String transString = "";
-                if(result.get("trans_result") != null){
-                    LOG.info("=====has trans result");
-
-                    JsonArray transResults = (JsonArray)result.get("trans_result");
-                    if(transResults.size()>0){
-                        LOG.info("=====has trans result 2");
-
-                        TranslateObj translateObj = gson.fromJson(transResults.get(0).getAsJsonObject(), TranslateObj.class);
-                        transString = translateObj.getDst();
-                        LOG.info("===transString==="+transString);
-                    }
-                }else{
-                    LOG.info("=====empty trans result");
-                    LOG.info(result.toString());
-                }
-                ((TextNode) node).text(transString);
-            }
-        }
-    }
 }

+ 62 - 2
hichina-main-back/src/main/java/com/hichina/main/back/hichinamainback/service/BaiduTranslateApiService.java

@@ -1,23 +1,39 @@
 package com.hichina.main.back.hichinamainback.service;
 
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
+import com.hichina.main.back.hichinamainback.model.DTO.TranslateObj;
 import com.hichina.main.back.hichinamainback.model.mongo.BaiduTranslateCache;
 import com.hichina.main.back.hichinamainback.repository.BaiduTranslateCacheRepository;
 import com.hichina.main.back.hichinamainback.utils.HttpUtils;
 import com.hichina.main.back.hichinamainback.utils.Md5Util;
+import com.hichina.main.back.hichinamainback.utils.RedisUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 @Service
 public class BaiduTranslateApiService {
     private static final Logger LOG = LoggerFactory.getLogger(BaiduTranslateApiService.class);
 
+    private static Gson gson = new Gson();
+
+    @Autowired
+    private RedisUtil redisUtil;
+
     private static final String TRANS_API_HOST = "http://api.fanyi.baidu.com/api/trans/vip/translate";
 
     @Autowired
@@ -35,8 +51,8 @@ public class BaiduTranslateApiService {
         JsonObject ret = HttpUtils.postUrlWithParams(TRANS_API_HOST, params);
         int retryCount = 0;
         int maxRetryCount = 3;
-        int minMilli = 300;
-        int maxMilli = 1000;
+        int minMilli = 500;
+        int maxMilli = 1100;
         while(retryCount++<maxRetryCount && ret.get("error_code")!=null && "54003".equals(ret.get("error_code").getAsString())){
             try {
                 int randomNum = minMilli + (int)(Math.random() * ((maxMilli - minMilli) + 1));
@@ -85,4 +101,48 @@ public class BaiduTranslateApiService {
 
         return params;
     }
+
+    @Async
+    public void triggerTranslationJobAsync(String translationKey, String query, String from, String to) {
+        String translatedText = "";
+        Document doc = Jsoup.parse(query);
+        htmlTextTagsTranslate(doc.childNodes(), from, to);
+        translatedText = doc.html();
+
+        cacheTranslation(translationKey, translatedText);
+
+        redisUtil.delete(translationKey);
+    }
+
+    private void htmlTextTagsTranslate(List<Node> nodes, String from, String to) {
+        for(Node node:nodes) {
+            htmlTextTagsTranslate(node.childNodes(), from, to);
+            if(node instanceof TextNode){
+                String originalText = ((TextNode) node).text();
+
+                if(StringUtils.isEmpty(originalText.trim())){
+                    LOG.info("==============empty text node skip========");
+                    continue;
+                }
+                JsonObject result = getTransResult(originalText, from, to);
+                String transString = "";
+                if(result.get("trans_result") != null){
+                    LOG.info("=====has trans result");
+
+                    JsonArray transResults = (JsonArray)result.get("trans_result");
+                    if(transResults.size()>0){
+                        LOG.info("=====has trans result 2");
+
+                        TranslateObj translateObj = gson.fromJson(transResults.get(0).getAsJsonObject(), TranslateObj.class);
+                        transString = translateObj.getDst();
+                        LOG.info("===transString==="+transString);
+                    }
+                }else{
+                    LOG.info("=====empty trans result");
+                    LOG.info(result.toString());
+                }
+                ((TextNode) node).text(transString);
+            }
+        }
+    }
 }

+ 13 - 3
hichina-main-front-mobile-first/src/pages/BlogDetailPage.vue

@@ -129,8 +129,12 @@ export default {
           console.log("baidu translate result title: ");
           console.log(res.data);
           if (res.data.ok == true) {
-            title.value = res.data.data;
+            if (res.data.data != null && res.data.data.length > 0) {
+              title.value = res.data.data;
+            }
+            gp.$generalNotify($q, true, res.data.message);
           } else {
+            gp.$generalNotify($q, false, res.data.message);
             console.log("translate title failed");
           }
 
@@ -138,6 +142,7 @@ export default {
         })
         .catch((err) => {
           console.log("err baidu translate title");
+          gp.$generalNotify($q, false, "err baidu translate title");
           gp.$hideLoading($q);
         });
     }
@@ -160,16 +165,21 @@ export default {
           console.log("baidu translate result: ");
           console.log(res.data);
           if (res.data.ok == true) {
-            content.value = res.data.data;
+            if (res.data.data != null && res.data.data.length > 0) {
+              content.value = res.data.data;
+            }
+            gp.$generalNotify($q, true, res.data.message);
             translateTitle();
           } else {
             console.log("translate failed");
+            gp.$generalNotify($q, false, res.data.message);
           }
 
           gp.$hideLoading($q);
         })
         .catch((err) => {
-          console.log("err baidu translate");
+          console.log("err baidu translate2");
+          gp.$generalNotify($q, false, "err baidu translate");
           gp.$hideLoading($q);
         });
     }