From d02187d552bc62fd9d15ee4ba4af2910ba82674c Mon Sep 17 00:00:00 2001 From: "chen.ma" Date: Sat, 25 Dec 2021 21:42:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E5=90=8E=EF=BC=8C=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=2030=20=E7=A7=92=E5=86=85=E6=97=A0=E6=B3=95=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=88=B0=E5=AE=9E=E4=BE=8B.=20(#42)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DynamicThreadPoolAutoConfiguration.java | 6 ++++ .../cn/hippo4j/starter/core/ClientWorker.java | 25 +++++++++------ .../starter/core/ThreadPoolConfigService.java | 9 +++++- .../event/ApplicationCompleteEvent.java | 23 ++++++++++++++ .../ApplicationContentPostProcessor.java | 31 +++++++++++++++++++ 5 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationCompleteEvent.java create mode 100644 hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationContentPostProcessor.java diff --git a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java index e6c793b1..7adc814a 100644 --- a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -7,6 +7,7 @@ import cn.hippo4j.starter.core.DynamicThreadPoolPostProcessor; import cn.hippo4j.starter.core.ThreadPoolConfigService; import cn.hippo4j.starter.core.ThreadPoolOperation; import cn.hippo4j.starter.enable.MarkerConfiguration; +import cn.hippo4j.starter.event.ApplicationContentPostProcessor; import cn.hippo4j.starter.handler.DynamicThreadPoolBannerHandler; import cn.hippo4j.starter.handler.ThreadPoolRunStateHandler; import cn.hippo4j.starter.monitor.ReportingEventExecutor; @@ -111,6 +112,11 @@ public class DynamicThreadPoolAutoConfiguration { return new RunTimeInfoCollector(properties); } + @Bean + public ApplicationContentPostProcessor applicationContentPostProcessor() { + return new ApplicationContentPostProcessor(); + } + } diff --git a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ClientWorker.java b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ClientWorker.java index a71076d1..4381d2ac 100644 --- a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ClientWorker.java +++ b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ClientWorker.java @@ -15,10 +15,7 @@ import org.springframework.util.StringUtils; import java.net.URLDecoder; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import static cn.hippo4j.common.constant.Constants.*; @@ -31,10 +28,10 @@ import static cn.hippo4j.common.constant.Constants.*; @Slf4j public class ClientWorker { - private double currentLongingTaskCount = 0; - private long timeout; + private double currentLongingTaskCount = 0; + private final HttpAgent agent; private final String identification; @@ -45,6 +42,8 @@ public class ClientWorker { private final ScheduledExecutorService executorService; + private final CountDownLatch awaitApplicationComplete = new CountDownLatch(1); + private final ConcurrentHashMap cacheMap = new ConcurrentHashMap(16); @SuppressWarnings("all") @@ -69,11 +68,15 @@ public class ClientWorker { this.executor.scheduleWithFixedDelay(() -> { try { + // 等待 spring 容器启动成功 + awaitApplicationComplete.await(); + + // 检查动态线程池配置是否被更新 checkConfigInfo(); } catch (Throwable e) { log.error("Sub check rotate check error.", e); } - }, 1L, 10L, TimeUnit.MILLISECONDS); + }, 1L, 1024L, TimeUnit.MILLISECONDS); } public void checkConfigInfo() { @@ -246,13 +249,13 @@ public class ClientWorker { cacheData = new CacheData(namespace, itemId, tpId); CacheData lastCacheData = cacheMap.putIfAbsent(tpId, cacheData); if (lastCacheData == null) { - String serverConfig = null; + String serverConfig; try { serverConfig = getServerConfig(namespace, itemId, tpId, 3000L); PoolParameterInfo poolInfo = JSONUtil.parseObject(serverConfig, PoolParameterInfo.class); cacheData.setContent(ContentUtil.getPoolContent(poolInfo)); } catch (Exception ex) { - log.error("[Cache Data] Error. Service Unavailable :: {}", ex.getMessage()); + log.error("Cache Data Error. Service Unavailable :: {}", ex.getMessage()); } int taskId = cacheMap.size() / CONFIG_LONG_POLL_TIMEOUT; @@ -268,4 +271,8 @@ public class ClientWorker { this.serverHealthCheck.setHealthStatus(isHealthServer); } + protected void notifyApplicationComplete() { + awaitApplicationComplete.countDown(); + } + } diff --git a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ThreadPoolConfigService.java b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ThreadPoolConfigService.java index c292df12..82d07f63 100644 --- a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ThreadPoolConfigService.java +++ b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ThreadPoolConfigService.java @@ -1,7 +1,9 @@ package cn.hippo4j.starter.core; +import cn.hippo4j.starter.event.ApplicationCompleteEvent; import cn.hippo4j.starter.remote.HttpAgent; import cn.hippo4j.starter.remote.ServerHealthCheck; +import org.springframework.context.ApplicationListener; import java.util.Arrays; @@ -11,7 +13,7 @@ import java.util.Arrays; * @author chen.ma * @date 2021/6/21 21:50 */ -public class ThreadPoolConfigService implements ConfigService { +public class ThreadPoolConfigService implements ConfigService, ApplicationListener { private final ClientWorker clientWorker; @@ -36,4 +38,9 @@ public class ThreadPoolConfigService implements ConfigService { } } + @Override + public void onApplicationEvent(ApplicationCompleteEvent event) { + clientWorker.notifyApplicationComplete(); + } + } diff --git a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationCompleteEvent.java b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationCompleteEvent.java new file mode 100644 index 00000000..d3ae2b65 --- /dev/null +++ b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationCompleteEvent.java @@ -0,0 +1,23 @@ +package cn.hippo4j.starter.event; + +import org.springframework.context.ApplicationEvent; + +/** + * Execute after the spring application context is successfully started. + * + * @author chen.ma + * @date 2021/12/25 21:19 + */ +public class ApplicationCompleteEvent extends ApplicationEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public ApplicationCompleteEvent(Object source) { + super(source); + } + +} diff --git a/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationContentPostProcessor.java b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationContentPostProcessor.java new file mode 100644 index 00000000..0a665f8e --- /dev/null +++ b/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/event/ApplicationContentPostProcessor.java @@ -0,0 +1,31 @@ +package cn.hippo4j.starter.event; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; + +import javax.annotation.Resource; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Application content post processor. + * + * @author chen.ma + * @date 2021/12/25 20:21 + */ +public class ApplicationContentPostProcessor implements ApplicationListener { + + @Resource + private ApplicationContext applicationContext; + + private AtomicBoolean executeOnlyOnce = new AtomicBoolean(Boolean.TRUE); + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (event.getApplicationContext().getParent() == null && executeOnlyOnce.get()) { + applicationContext.publishEvent(new ApplicationCompleteEvent(this)); + executeOnlyOnce.set(Boolean.FALSE); + } + } + +}