opai服务管理
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
6.7 KiB

  1. package com.bw.convert.handler;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.concurrent.LinkedBlockingDeque;
  7. import java.util.concurrent.LinkedBlockingQueue;
  8. import java.util.concurrent.ThreadPoolExecutor;
  9. import java.util.concurrent.TimeUnit;
  10. import org.apache.commons.io.FileUtils;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.beans.factory.annotation.Value;
  13. import org.springframework.boot.ApplicationArguments;
  14. import org.springframework.boot.ApplicationRunner;
  15. import org.springframework.core.annotation.Order;
  16. import org.springframework.stereotype.Component;
  17. import com.alibaba.fastjson.JSONObject;
  18. import com.bw.convert.cache.ConfigCache;
  19. import com.bw.convert.service.ConvertTaskService;
  20. import com.bw.convert.utils.DateUtil;
  21. import com.bw.convert.utils.FileUtil;
  22. import lombok.extern.slf4j.Slf4j;
  23. /**
  24. * @author jian.mao
  25. * @date 2025年1月13日
  26. * @description
  27. */
  28. @Component
  29. @Order(value = 1)
  30. @Slf4j
  31. public class MainHandler implements ApplicationRunner {
  32. @Value("${task.task-queue-path}")
  33. private String taskPath;
  34. @Value("${task.result-task-queue-path}")
  35. private String resultTaskPath;
  36. @Autowired
  37. private ConvertTaskService convertTaskService;
  38. /***线程池参数***/
  39. @Value("${threadPool.corePoolSize}")
  40. private int corePoolSize;
  41. @Value("${threadPool.maximumPoolSize}")
  42. private int maximumPoolSize;
  43. @Value("${threadPool.keepAliveTime}")
  44. private long keepAliveTime;
  45. @Value("${threadPool.queueSize}")
  46. private int queueSize;
  47. /**
  48. *执行入口
  49. */
  50. @Override
  51. public void run(ApplicationArguments args) throws Exception {
  52. //线程池方式
  53. ThreadPoolExecutor executor = new ThreadPoolExecutor(
  54. corePoolSize,
  55. maximumPoolSize,
  56. keepAliveTime,
  57. TimeUnit.SECONDS,
  58. new LinkedBlockingQueue<>(queueSize),
  59. new ThreadPoolExecutor.CallerRunsPolicy()
  60. );
  61. //消费创建任务队列数据
  62. Thread consumerThread = new Thread(() -> {
  63. while (true) {
  64. try {
  65. // 从队列中获取任务
  66. Map<String, Object> task = ConfigCache.taskQueue.take();
  67. log.info("创建任务----:{}",JSONObject.toJSONString(task));
  68. // 提交给线程池执行
  69. executor.execute(() -> createTask(task));
  70. } catch (InterruptedException e) {
  71. // 恢复中断状态
  72. Thread.currentThread().interrupt();
  73. log.error("任务消费线程被中断");
  74. break;
  75. }
  76. }
  77. });
  78. consumerThread.start();
  79. log.info("创建任务消费线程启动-----");
  80. //消费结果任务队列数据
  81. Thread resultConsumerThread = new Thread(() -> {
  82. while (true) {
  83. try {
  84. // 从队列中获取任务
  85. Map<String, Object> task = ConfigCache.resultQueue.take();
  86. log.info("获取结果任务----:{}",JSONObject.toJSONString(task));
  87. // 提交给线程池执行
  88. executor.execute(() -> getResult(task));
  89. } catch (InterruptedException e) {
  90. // 恢复中断状态
  91. Thread.currentThread().interrupt();
  92. log.error("任务消费线程被中断");
  93. break;
  94. }
  95. DateUtil.sleep(3000);
  96. }
  97. });
  98. resultConsumerThread.start();
  99. log.info("结果任务消费线程启动-----");
  100. //启动加载缓存任务
  101. readTask(taskPath, ConfigCache.taskQueue);
  102. readTask(resultTaskPath, ConfigCache.resultQueue);
  103. //停止处理
  104. waitDown();
  105. }
  106. /**
  107. * 创建任务执行方法
  108. * @param task
  109. */
  110. private void createTask(Map<String, Object> task) {
  111. convertTaskService.create(task);
  112. }
  113. private void getResult(Map<String, Object> task) {
  114. convertTaskService.parse(task);
  115. }
  116. /****************************************************************load******************************************************************************/
  117. /**
  118. * 加载文件中的任务
  119. * @param path 文件地址
  120. * @param queue 队列
  121. */
  122. @SuppressWarnings("unchecked")
  123. public static void readTask(String path, LinkedBlockingDeque<Map<String, Object>> queue) {
  124. File file = new File(path);
  125. if (file.exists()) {
  126. List<String> tasks = null;
  127. try {
  128. tasks = FileUtils.readLines(file, "UTF-8");
  129. } catch (IOException e) {
  130. e.printStackTrace();
  131. }
  132. for (String taskStr : tasks) {
  133. Map<String, Object> task = JSONObject.parseObject(taskStr);
  134. try {
  135. queue.put(task);
  136. } catch (InterruptedException e) {
  137. e.printStackTrace();
  138. }
  139. }
  140. file.delete();
  141. }
  142. }
  143. /*******************************************************************stop************************************************************************/
  144. /**
  145. * 结束触发钩子
  146. */
  147. public void waitDown() {
  148. Runtime.getRuntime().addShutdownHook(new Thread() {
  149. @Override
  150. public void run() {
  151. // 停止线程
  152. ConfigCache.isStart = false;
  153. log.info("stop-------");
  154. writeTsskToFile();
  155. }
  156. });
  157. }
  158. /**
  159. * 任务持久化到硬盘
  160. */
  161. public void writeTsskToFile() {
  162. while (true) {
  163. if (ConfigCache.taskQueue.size() > 0) {
  164. try {
  165. Map<String, Object> task = ConfigCache.taskQueue.take();
  166. FileUtil.writeFile(taskPath, JSONObject.toJSONString(task));
  167. } catch (InterruptedException e) {
  168. e.printStackTrace();
  169. }
  170. } else {
  171. log.info("taskQueue write is file end");
  172. break;
  173. }
  174. }
  175. while (true) {
  176. if (ConfigCache.resultQueue.size() > 0) {
  177. try {
  178. Map<String, Object> task = ConfigCache.resultQueue.take();
  179. FileUtil.writeFile(resultTaskPath, JSONObject.toJSONString(task));
  180. } catch (InterruptedException e) {
  181. e.printStackTrace();
  182. }
  183. } else {
  184. log.info("taskQueue write is file end");
  185. break;
  186. }
  187. }
  188. }
  189. }