[ Execution ] change the excuetion log access way

This commit is contained in:
IceDerce
2023-06-16 10:55:24 +08:00
parent 1aa4c23dfc
commit 93692eb0af
5 changed files with 539 additions and 549 deletions

View File

@@ -4,7 +4,6 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import io.wdd.common.response.R; import io.wdd.common.response.R;
import io.wdd.rpc.execute.result.BuildStreamReader;
import io.wdd.rpc.execute.service.AsyncExecutionService; import io.wdd.rpc.execute.service.AsyncExecutionService;
import io.wdd.rpc.execute.service.SyncExecutionService; import io.wdd.rpc.execute.service.SyncExecutionService;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@@ -18,7 +17,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static io.wdd.rpc.execute.result.RedisStreamReaderConfig.AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER;
import static io.wdd.rpc.init.AgentStatusCacheService.ALL_AGENT_TOPIC_NAME_LIST; import static io.wdd.rpc.init.AgentStatusCacheService.ALL_AGENT_TOPIC_NAME_LIST;
import static io.wdd.rpc.init.AgentStatusCacheService.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST; import static io.wdd.rpc.init.AgentStatusCacheService.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST;
@@ -30,8 +28,6 @@ public class ExecutionController {
@Resource @Resource
SyncExecutionService syncExecutionService; SyncExecutionService syncExecutionService;
@Resource @Resource
BuildStreamReader buildStreamReader;
@Resource
AsyncExecutionService asyncExecutionService; AsyncExecutionService asyncExecutionService;
@PostMapping("/command/one") @PostMapping("/command/one")
@@ -198,11 +194,6 @@ public class ExecutionController {
@RequestParam(value = "streamKey") @ApiParam(value = "status的Stream Key") String streamKey @RequestParam(value = "streamKey") @ApiParam(value = "status的Stream Key") String streamKey
) { ) {
buildStreamReader.registerStreamReader(
AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER,
streamKey
);
return R.ok("请到控制台查看,已经切换至 => " + streamKey); return R.ok("请到控制台查看,已经切换至 => " + streamKey);
} }

View File

@@ -1,27 +1,26 @@
package io.wdd.rpc.execute.config; //package io.wdd.rpc.execute.config;
//
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
//
import static io.wdd.rpc.execute.result.RedisStreamReaderConfig.REDIS_STREAM_LISTENER_CONSUMER_NAME; //
//@Configuration
@Configuration //public class CommandReaderConfigBean {
public class CommandReaderConfigBean { //
// // todo must support for multi thread
// todo must support for multi thread // // its not thread safe now
// its not thread safe now // @Bean
@Bean // public CommandReaderConfig commandReaderConfig() {
public CommandReaderConfig commandReaderConfig() { //
// return CommandReaderConfig
return CommandReaderConfig // .builder()
.builder() // .consumerName(REDIS_STREAM_LISTENER_CONSUMER_NAME)
.consumerName(REDIS_STREAM_LISTENER_CONSUMER_NAME) // .streamKey("ccc")
.streamKey("ccc") // .consumerType(REDIS_STREAM_LISTENER_CONSUMER_NAME)
.consumerType(REDIS_STREAM_LISTENER_CONSUMER_NAME) // .group("ccc")
.group("ccc") // .ExecutionResult(null)
.ExecutionResult(null) // .build();
.build(); // }
} //
//
//}
}

View File

@@ -1,189 +1,189 @@
package io.wdd.rpc.execute.result; //package io.wdd.rpc.execute.result;
//
import io.wdd.rpc.execute.config.CommandReaderConfig; //import io.wdd.rpc.execute.config.CommandReaderConfig;
import io.wdd.server.utils.SpringUtils; //import io.wdd.server.utils.SpringUtils;
import lombok.SneakyThrows; //import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.stream.ReadOffset; //import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset; //import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.stream.StreamMessageListenerContainer; //import org.springframework.data.redis.stream.StreamMessageListenerContainer;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.HashMap; //import java.util.HashMap;
import java.util.concurrent.TimeUnit; //import java.util.concurrent.TimeUnit;
//
import static io.wdd.rpc.execute.result.RedisStreamReaderConfig.EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER; //import static io.wdd.rpc.execute.result.RedisStreamReaderConfig.EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER;
//
//
@Component //@Component
@Slf4j //@Slf4j
public class BuildStreamReader { //public class BuildStreamReader {
//
private final HashMap<String, StreamMessageListenerContainer> REDIS_STREAM_LISTENER_CONTAINER_CACHE = new HashMap<>(16); // private final HashMap<String, StreamMessageListenerContainer> REDIS_STREAM_LISTENER_CONTAINER_CACHE = new HashMap<>(16);
private RedisStreamReaderConfig redisStreamReaderConfig; // private RedisStreamReaderConfig redisStreamReaderConfig;
//
private StreamMessageListenerContainer streamMessageListenerContainer; // private StreamMessageListenerContainer streamMessageListenerContainer;
//
private CommandReaderConfig commandReaderConfig; // private CommandReaderConfig commandReaderConfig;
//
public void buildStreamReader(CommandReaderConfig commandReaderConfig) { // public void buildStreamReader(CommandReaderConfig commandReaderConfig) {
//
// prepare the environment // // prepare the environment
prepareExecutionEnv(); // prepareExecutionEnv();
//
//
// just modify the redis listener container and it's ok // // just modify the redis listener container and it's ok
modifyExecutionStreamReader(commandReaderConfig); // modifyExecutionStreamReader(commandReaderConfig);
//
} // }
//
@SneakyThrows // @SneakyThrows
private void modifyExecutionStreamReader(CommandReaderConfig commandReaderConfig) { // private void modifyExecutionStreamReader(CommandReaderConfig commandReaderConfig) {
//
// stop the old stream listener container // // stop the old stream listener container
if (this.streamMessageListenerContainer.isRunning()) { // if (this.streamMessageListenerContainer.isRunning()) {
this.streamMessageListenerContainer.stop(); // this.streamMessageListenerContainer.stop();
} // }
//
// modify container // // modify container
this.streamMessageListenerContainer.receive( // this.streamMessageListenerContainer.receive(
StreamOffset.create( // StreamOffset.create(
commandReaderConfig.getStreamKey(), // commandReaderConfig.getStreamKey(),
ReadOffset.lastConsumed()), // ReadOffset.lastConsumed()),
//
new CommandResultReader( // new CommandResultReader(
commandReaderConfig // commandReaderConfig
) // )
); // );
//
//
// very important // // very important
TimeUnit.MILLISECONDS.sleep(500); // TimeUnit.MILLISECONDS.sleep(500);
this.streamMessageListenerContainer.start(); // this.streamMessageListenerContainer.start();
} // }
//
private void prepareExecutionEnv() { // private void prepareExecutionEnv() {
//
getRedisStreamListenerContainer(); // getRedisStreamListenerContainer();
//
getRedisStreamReaderConfig(); // getRedisStreamReaderConfig();
//
} // }
//
private void getRedisStreamReaderConfig() { // private void getRedisStreamReaderConfig() {
//
this.commandReaderConfig = SpringUtils.getBean("commandReaderConfig", // this.commandReaderConfig = SpringUtils.getBean("commandReaderConfig",
CommandReaderConfig.class); // CommandReaderConfig.class);
} // }
//
private void getRedisStreamListenerContainer() { // private void getRedisStreamListenerContainer() {
//
this.streamMessageListenerContainer = SpringUtils.getBean( // this.streamMessageListenerContainer = SpringUtils.getBean(
EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER, // EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER,
StreamMessageListenerContainer.class // StreamMessageListenerContainer.class
); // );
} // }
//
public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey) { // public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey) {
registerStreamReader(redisStreamListenerContainerBeanName, // registerStreamReader(redisStreamListenerContainerBeanName,
streamKey, // streamKey,
null); // null);
} // }
//
public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey, ArrayList<String> ExecutionResult) { // public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey, ArrayList<String> ExecutionResult) {
//
// prepare the environment // // prepare the environment
prepareEnv(); // prepareEnv();
//
// oldStreamKey equals streamKey don't need to do anything , just return // // oldStreamKey equals streamKey don't need to do anything , just return
if (redisStreamReaderConfig.getStreamKey() // if (redisStreamReaderConfig.getStreamKey()
.equals(streamKey)) { // .equals(streamKey)) {
log.debug("redis listener container not change !"); // log.debug("redis listener container not change !");
return; // return;
} // }
//
// destroy the old REDIS_STREAM_LISTENER_CONTAINER // // destroy the old REDIS_STREAM_LISTENER_CONTAINER
destroyStreamReader(streamKey); // destroyStreamReader(streamKey);
//
// modify the configuration ==> streamKey // // modify the configuration ==> streamKey
modifyStreamReader(streamKey, // modifyStreamReader(streamKey,
ExecutionResult); // ExecutionResult);
//
// re-create the REDIS_STREAM_LISTENER_CONTAINER // // re-create the REDIS_STREAM_LISTENER_CONTAINER
createStreamReader(redisStreamListenerContainerBeanName, // createStreamReader(redisStreamListenerContainerBeanName,
streamKey); // streamKey);
//
} // }
//
private void prepareEnv() { // private void prepareEnv() {
//
getRedisStreamConfig(); // getRedisStreamConfig();
//
} // }
//
private void getRedisStreamConfig() { // private void getRedisStreamConfig() {
//
this.redisStreamReaderConfig = SpringUtils.getBean("redisStreamReaderConfig", // this.redisStreamReaderConfig = SpringUtils.getBean("redisStreamReaderConfig",
RedisStreamReaderConfig.class); // RedisStreamReaderConfig.class);
} // }
//
//
private void createStreamReader(String redisStreamListenerContainerBeanName, String streamKey) { // private void createStreamReader(String redisStreamListenerContainerBeanName, String streamKey) {
//
log.debug("start to create the redis stream listener container"); // log.debug("start to create the redis stream listener container");
// create the lazy bean // // create the lazy bean
//
StreamMessageListenerContainer streamMessageListenerContainer = SpringUtils.getBean(redisStreamListenerContainerBeanName, // StreamMessageListenerContainer streamMessageListenerContainer = SpringUtils.getBean(redisStreamListenerContainerBeanName,
StreamMessageListenerContainer.class); // StreamMessageListenerContainer.class);
//
REDIS_STREAM_LISTENER_CONTAINER_CACHE.put(streamKey, // REDIS_STREAM_LISTENER_CONTAINER_CACHE.put(streamKey,
streamMessageListenerContainer); // streamMessageListenerContainer);
//
// very important // // very important
log.debug("start the listener container"); // log.debug("start the listener container");
streamMessageListenerContainer.start(); // streamMessageListenerContainer.start();
//
//
} // }
//
private void modifyStreamReader(String streamKey, ArrayList<String> executionResult) { // private void modifyStreamReader(String streamKey, ArrayList<String> executionResult) {
//
log.debug("start to modify the redis stream listener container stream key"); // log.debug("start to modify the redis stream listener container stream key");
String oldStreamKey = redisStreamReaderConfig.getStreamKey(); // String oldStreamKey = redisStreamReaderConfig.getStreamKey();
//
log.debug("change stream key from [{}] to [{}]", // log.debug("change stream key from [{}] to [{}]",
oldStreamKey, // oldStreamKey,
streamKey); // streamKey);
//
log.debug("start to set the Redis Stream Reader key"); // log.debug("start to set the Redis Stream Reader key");
redisStreamReaderConfig.setStreamKey(streamKey); // redisStreamReaderConfig.setStreamKey(streamKey);
//
log.debug("start to set the Redis Stream Execution Result Container"); // log.debug("start to set the Redis Stream Execution Result Container");
redisStreamReaderConfig.setExecutionResult(executionResult); // redisStreamReaderConfig.setExecutionResult(executionResult);
//
} // }
//
//
private void destroyStreamReader(String streamKey) { // private void destroyStreamReader(String streamKey) {
//
String oldStreamKey = redisStreamReaderConfig.getStreamKey(); // String oldStreamKey = redisStreamReaderConfig.getStreamKey();
//
if (REDIS_STREAM_LISTENER_CONTAINER_CACHE.containsKey(oldStreamKey)) { // if (REDIS_STREAM_LISTENER_CONTAINER_CACHE.containsKey(oldStreamKey)) {
//
StreamMessageListenerContainer streamMessageListenerContainer = REDIS_STREAM_LISTENER_CONTAINER_CACHE.get(oldStreamKey); // StreamMessageListenerContainer streamMessageListenerContainer = REDIS_STREAM_LISTENER_CONTAINER_CACHE.get(oldStreamKey);
//
log.debug("destroyed old redis stream listener container is [ {} ]", // log.debug("destroyed old redis stream listener container is [ {} ]",
streamMessageListenerContainer); // streamMessageListenerContainer);
//
//
// double destroy // // double destroy
SpringUtils.destroyBean(streamMessageListenerContainer); // SpringUtils.destroyBean(streamMessageListenerContainer);
streamMessageListenerContainer.stop(); // streamMessageListenerContainer.stop();
// help gc // // help gc
streamMessageListenerContainer = null; // streamMessageListenerContainer = null;
} // }
//
//
} // }
} //}

View File

@@ -1,121 +1,121 @@
package io.wdd.rpc.execute.result; //package io.wdd.rpc.execute.result;
//
//
import io.wdd.rpc.scheduler.service.status.AgentStatusStreamReader; //import io.wdd.rpc.scheduler.service.status.AgentStatusStreamReader;
import lombok.Getter; //import lombok.Getter;
import lombok.Setter; //import lombok.Setter;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; //import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope; //import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.RedisConnectionFactory; //import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.stream.MapRecord; //import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.connection.stream.ReadOffset; //import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset; //import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.stream.StreamMessageListenerContainer; //import org.springframework.data.redis.stream.StreamMessageListenerContainer;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.time.Duration; //import java.time.Duration;
import java.util.ArrayList; //import java.util.ArrayList;
//
@Configuration //@Configuration
@Slf4j //@Slf4j
@Getter //@Getter
@Setter //@Setter
public class RedisStreamReaderConfig { //public class RedisStreamReaderConfig {
//
@Resource // @Resource
private RedisConnectionFactory redisConnectionFactory; // private RedisConnectionFactory redisConnectionFactory;
//
public static final String COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER = "commandResultRedisStreamListenerContainer"; // public static final String COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER = "commandResultRedisStreamListenerContainer";
//
public static final String EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER = "executionResultRedisStreamListenerContainer"; // public static final String EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER = "executionResultRedisStreamListenerContainer";
//
public static final String AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER = "agentStatusRedisStreamListenerContainer"; // public static final String AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER = "agentStatusRedisStreamListenerContainer";
//
public static final String REDIS_STREAM_LISTENER_CONSUMER_NAME = "OctopusServer"; // public static final String REDIS_STREAM_LISTENER_CONSUMER_NAME = "OctopusServer";
//
/** // /**
* used in old model // * used in old model
*/ // */
private String streamKey = "cccc"; // private String streamKey = "cccc";
//
/** // /**
* no use // * no use
*/ // */
private ArrayList<String> executionResult = null; // private ArrayList<String> executionResult = null;
//
//
@Bean(value = EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER) // @Bean(value = EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER)
@Lazy // @Lazy
public StreamMessageListenerContainer<String, MapRecord<String, String, String>> executionResultRedisStreamListenerContainer(){ // public StreamMessageListenerContainer<String, MapRecord<String, String, String>> executionResultRedisStreamListenerContainer(){
//
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions // StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofSeconds(2)) // .pollTimeout(Duration.ofSeconds(2))
.build(); // .build();
//
StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options); // StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options);
//
return listenerContainer; // return listenerContainer;
} // }
//
//
@Bean(value = COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER) // @Bean(value = COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER)
@Scope("prototype") // @Scope("prototype")
@Lazy // @Lazy
public StreamMessageListenerContainer<String, MapRecord<String, String, String>> commandResultRedisStreamListenerContainer(){ // public StreamMessageListenerContainer<String, MapRecord<String, String, String>> commandResultRedisStreamListenerContainer(){
//
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions // StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofSeconds(2)) // .pollTimeout(Duration.ofSeconds(2))
.build(); // .build();
//
StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options); // StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options);
//
// todo 此部分可以被移出到另外的位置会更加方便就不需要对此Bean进行创建和销毁了 // // todo 此部分可以被移出到另外的位置会更加方便就不需要对此Bean进行创建和销毁了
listenerContainer.receive( // listenerContainer.receive(
//
StreamOffset.create(streamKey, ReadOffset.lastConsumed()), // StreamOffset.create(streamKey, ReadOffset.lastConsumed()),
//
new CommandResultReader( // new CommandResultReader(
REDIS_STREAM_LISTENER_CONSUMER_NAME, // REDIS_STREAM_LISTENER_CONSUMER_NAME,
streamKey, // streamKey,
REDIS_STREAM_LISTENER_CONSUMER_NAME, // REDIS_STREAM_LISTENER_CONSUMER_NAME,
executionResult // executionResult
) // )
//
); // );
//
return listenerContainer; // return listenerContainer;
} // }
//
@Bean(value = AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER) // @Bean(value = AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER)
@Scope("prototype") // @Scope("prototype")
@Lazy // @Lazy
public StreamMessageListenerContainer<String, MapRecord<String, String, String>> agentStatusRedisStreamListenerContainer(){ // public StreamMessageListenerContainer<String, MapRecord<String, String, String>> agentStatusRedisStreamListenerContainer(){
//
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions // StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofSeconds(2)) // .pollTimeout(Duration.ofSeconds(2))
.build(); // .build();
//
StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options); // StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options);
//
listenerContainer.receive( // listenerContainer.receive(
//
StreamOffset.create(streamKey, ReadOffset.lastConsumed()), // StreamOffset.create(streamKey, ReadOffset.lastConsumed()),
//
new AgentStatusStreamReader( // new AgentStatusStreamReader(
REDIS_STREAM_LISTENER_CONSUMER_NAME, // REDIS_STREAM_LISTENER_CONSUMER_NAME,
REDIS_STREAM_LISTENER_CONSUMER_NAME, // REDIS_STREAM_LISTENER_CONSUMER_NAME,
REDIS_STREAM_LISTENER_CONSUMER_NAME) // REDIS_STREAM_LISTENER_CONSUMER_NAME)
//
); // );
//
return listenerContainer; // return listenerContainer;
} // }
//
//
} //}

View File

@@ -1,203 +1,203 @@
package io.wdd.rpc.execute.service; //package io.wdd.rpc.execute.service;
//
//
import io.wdd.common.utils.TimeUtils; //import io.wdd.common.utils.TimeUtils;
import io.wdd.rpc.execute.config.CommandReaderConfig; //import io.wdd.rpc.execute.config.CommandReaderConfig;
import io.wdd.rpc.execute.config.ExecutionLog; //import io.wdd.rpc.execute.config.ExecutionLog;
import io.wdd.rpc.execute.result.BuildStreamReader; //import io.wdd.rpc.execute.result.BuildStreamReader;
import io.wdd.server.service.ExecutionLogService; //import io.wdd.server.service.ExecutionLogService;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; //import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.annotation.Lazy; //import org.springframework.context.annotation.Lazy;
//
import javax.annotation.PostConstruct; //import javax.annotation.PostConstruct;
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.Collection; //import java.util.Collection;
import java.util.List; //import java.util.List;
import java.util.concurrent.*; //import java.util.concurrent.*;
//
/** ///**
* 1. [waiting strategy ] // * 1. [waiting strategy ]
* 2. [build the redis stream listener] // * 2. [build the redis stream listener]
* 3. [call persistence] // * 3. [call persistence]
*/ // */
//@Service ////@Service
@Slf4j //@Slf4j
@Lazy //@Lazy
@Deprecated //@Deprecated
public class ExecutionResultDaemonHandler { //public class ExecutionResultDaemonHandler {
//
/** // /**
* store all execution result key // * store all execution result key
* <p> // * <p>
* which means there are execution running , waiting for their result to handle // * which means there are execution running , waiting for their result to handle
*/ // */
public static final ConcurrentHashMap<String, ExecutionLog> WAIT_EXECUTION_RESULT_LIST = new ConcurrentHashMap<>(32); // public static final ConcurrentHashMap<String, ExecutionLog> WAIT_EXECUTION_RESULT_LIST = new ConcurrentHashMap<>(32);
private final int MAX_TIMEOUT_WAITING_FOR_EXECUTION_RESULT = 70; // private final int MAX_TIMEOUT_WAITING_FOR_EXECUTION_RESULT = 70;
//
@Resource // @Resource
BuildStreamReader buildStreamReader; // BuildStreamReader buildStreamReader;
//
@Resource // @Resource
CommandReaderConfig commandReaderConfig; // CommandReaderConfig commandReaderConfig;
//
@Resource // @Resource
ExecutionLogService executionLogService; // ExecutionLogService executionLogService;
//
@PostConstruct // @PostConstruct
public void startExecutionDaemonHandler() { // public void startExecutionDaemonHandler() {
//
// 启动一个异步线程,运行 Execution结果处理守护进程 // // 启动一个异步线程,运行 Execution结果处理守护进程
CompletableFuture.runAsync( // CompletableFuture.runAsync(
() -> realStartExecutionDaemonHandler() // () -> realStartExecutionDaemonHandler()
); // );
//
} // }
//
private void realStartExecutionDaemonHandler() { // private void realStartExecutionDaemonHandler() {
//
while (true) { // while (true) {
//
while (WAIT_EXECUTION_RESULT_LIST.size() == 0) { // while (WAIT_EXECUTION_RESULT_LIST.size() == 0) {
try { // try {
// no execution result need to handle // // no execution result need to handle
//
// wait for 5 seconds // // wait for 5 seconds
log.debug("realStartExecutionDaemonHandler start to sleep waiting for result !"); // log.debug("realStartExecutionDaemonHandler start to sleep waiting for result !");
TimeUnit.SECONDS.sleep(5); // TimeUnit.SECONDS.sleep(5);
//
} catch (InterruptedException e) { // } catch (InterruptedException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
//
// has result to handle , just handle one result at one time // // has result to handle , just handle one result at one time
String resultKey = WAIT_EXECUTION_RESULT_LIST // String resultKey = WAIT_EXECUTION_RESULT_LIST
.keys() // .keys()
.nextElement(); // .nextElement();
//
log.debug( // log.debug(
"current result key is [{}]", // "current result key is [{}]",
resultKey // resultKey
); // );
//
//
CompletableFuture<ArrayList<String>> executionResultFuture = // CompletableFuture<ArrayList<String>> executionResultFuture =
CompletableFuture // CompletableFuture
.supplyAsync( // .supplyAsync(
() -> { // () -> {
// 修改相应的参数 // // 修改相应的参数
commandReaderConfig.setStreamKey(resultKey); // commandReaderConfig.setStreamKey(resultKey);
// listener container 实际上是根据这个绑定的 // // listener container 实际上是根据这个绑定的
commandReaderConfig.setGroup(resultKey); // commandReaderConfig.setGroup(resultKey);
// 必须归零 // // 必须归零
commandReaderConfig.setExecutionResult(null); // commandReaderConfig.setExecutionResult(null);
//
// 构造 resultKey对应的 Redis Stream Listener Container // // 构造 resultKey对应的 Redis Stream Listener Container
buildStreamReader // buildStreamReader
.buildStreamReader(commandReaderConfig); // .buildStreamReader(commandReaderConfig);
//
// 获得结果 // // 获得结果
ArrayList<String> s = new ArrayList<>( // ArrayList<String> s = new ArrayList<>(
List.of("no no no") // List.of("no no no")
); // );
//
try { // try {
s = CompletableFuture // s = CompletableFuture
.supplyAsync( // .supplyAsync(
() -> { // () -> {
while (true) { // while (true) {
// todo 多条命令时,这里只能获取到一个结果 // // todo 多条命令时,这里只能获取到一个结果
if (CollectionUtils.isNotEmpty(commandReaderConfig.getExecutionResult())) { // if (CollectionUtils.isNotEmpty(commandReaderConfig.getExecutionResult())) {
return commandReaderConfig.getExecutionResult(); // return commandReaderConfig.getExecutionResult();
} // }
//
try { // try {
TimeUnit.SECONDS.sleep(3); // TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) { // } catch (InterruptedException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
} // }
) // )
// 获取相应的结果 // // 获取相应的结果
.get( // .get(
MAX_TIMEOUT_WAITING_FOR_EXECUTION_RESULT, // MAX_TIMEOUT_WAITING_FOR_EXECUTION_RESULT,
TimeUnit.SECONDS // TimeUnit.SECONDS
); // );
} catch (InterruptedException e) { // } catch (InterruptedException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} catch (ExecutionException e) { // } catch (ExecutionException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} catch (TimeoutException e) { // } catch (TimeoutException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
//
//
return s; // return s;
} // }
); // );
//
CompletableFuture<ArrayList<String>> falloutTimeFuture = CompletableFuture.supplyAsync( // CompletableFuture<ArrayList<String>> falloutTimeFuture = CompletableFuture.supplyAsync(
() -> { // () -> {
try { // try {
TimeUnit.SECONDS.sleep(MAX_TIMEOUT_WAITING_FOR_EXECUTION_RESULT); // TimeUnit.SECONDS.sleep(MAX_TIMEOUT_WAITING_FOR_EXECUTION_RESULT);
} catch (InterruptedException e) { // } catch (InterruptedException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
//
return null; // return null;
} // }
); // );
//
// 获取结果然后销毁Stream Listener Container // // 获取结果然后销毁Stream Listener Container
CompletableFuture<Object> complete = CompletableFuture // CompletableFuture<Object> complete = CompletableFuture
.anyOf( // .anyOf(
falloutTimeFuture, // falloutTimeFuture,
executionResultFuture // executionResultFuture
); // );
//
complete // complete
.whenComplete( // .whenComplete(
(result, e) -> { // (result, e) -> {
//
log.debug( // log.debug(
"execution result are => {}", // "execution result are => {}",
result // result
); // );
//
// 持久化存储对应的结果 // // 持久化存储对应的结果
ExecutionLog executionLog = WAIT_EXECUTION_RESULT_LIST.get(resultKey); // ExecutionLog executionLog = WAIT_EXECUTION_RESULT_LIST.get(resultKey);
executionLog.setAcTime(TimeUtils.currentTime()); // executionLog.setAcTime(TimeUtils.currentTime());
executionLog.setResultContent(String.valueOf(commandReaderConfig.getExecutionResult())); // executionLog.setResultContent(String.valueOf(commandReaderConfig.getExecutionResult()));
executionLog.setResultCode( // executionLog.setResultCode(
CollectionUtils.isEmpty((Collection) result) ? 1 : 0 // CollectionUtils.isEmpty((Collection) result) ? 1 : 0
); // );
executionLog.setRecordId(commandReaderConfig.getRecordId()); // executionLog.setRecordId(commandReaderConfig.getRecordId());
//
//
// 保存操作 // // 保存操作
executionLogService.save(executionLog); // executionLogService.save(executionLog);
//
// 清除此次任务的内容 // // 清除此次任务的内容
WAIT_EXECUTION_RESULT_LIST.remove(resultKey); // WAIT_EXECUTION_RESULT_LIST.remove(resultKey);
log.info( // log.info(
"[Execution] - command {} result are {} result code is {} ,whole process are complete !", // "[Execution] - command {} result are {} result code is {} ,whole process are complete !",
executionLog.getCommandList(), // executionLog.getCommandList(),
executionLog.getResultContent(), // executionLog.getResultContent(),
executionLog.getResultCode() // executionLog.getResultCode()
); // );
} // }
); // );
//
// very important // // very important
// stuck the main thread , otherwise it will create a dead loop // // stuck the main thread , otherwise it will create a dead loop
complete.join(); // complete.join();
//
} // }
//
} // }
//
//
} //}