mirror of https://github.com/longtai-cn/hippo4j
Refactor the code to build the kernel layer (#1322)
parent
845c32fdca
commit
10b3767df1
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-agent-plugin</artifactId>
|
||||||
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>hippo4j-agent-adapter-plugins</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-agent-mode</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>hippo4j-agent-config-mode</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>apollo-plugin</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-agent-plugin</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>hippo4j-agent-mode</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>config</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
19
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/DynamicThreadPoolChangeHandlerSpring1x.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/DynamicThreadPoolChangeHandlerSpring1x.java
19
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/DynamicThreadPoolChangeHandlerSpring1x.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/DynamicThreadPoolChangeHandlerSpring1x.java
0
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java
0
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java
0
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/EventPublishingFinishedInterceptor.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/EventPublishingFinishedInterceptor.java
0
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/EventPublishingFinishedInterceptor.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/EventPublishingFinishedInterceptor.java
15
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java
15
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java
0
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java
0
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java
3
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/interceptor/EventPublishingStartedInterceptor.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/interceptor/EventPublishingStartedInterceptor.java
3
agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/interceptor/EventPublishingStartedInterceptor.java → agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/interceptor/EventPublishingStartedInterceptor.java
4
agent/hippo4j-agent-plugin/thread-pool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java → agent/hippo4j-agent-plugin/threadpool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java
4
agent/hippo4j-agent-plugin/thread-pool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java → agent/hippo4j-agent-plugin/threadpool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cn.hippo4j.threadpool.dynamic.core.executor.manage;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global thread-pool manage.
|
||||||
|
*/
|
||||||
|
public class GlobalThreadPoolManage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic thread pool parameter container.
|
||||||
|
*/
|
||||||
|
private static final Map<String, ThreadPoolParameter> POOL_PARAMETER = new ConcurrentHashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic thread pool wrapper.
|
||||||
|
*/
|
||||||
|
private static final Map<String, ThreadPoolExecutor> EXECUTOR_MAP = new ConcurrentHashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the dynamic thread pool class.
|
||||||
|
*
|
||||||
|
* @param threadPoolId thread-pool id
|
||||||
|
* @return dynamic thread-pool
|
||||||
|
*/
|
||||||
|
public static ThreadPoolExecutor getExecutorService(String threadPoolId) {
|
||||||
|
return EXECUTOR_MAP.get(threadPoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get dynamic thread pool parameters.
|
||||||
|
*
|
||||||
|
* @param threadPoolId thread-pool id
|
||||||
|
* @return thread-pool parameter
|
||||||
|
*/
|
||||||
|
public static ThreadPoolParameter getPoolParameter(String threadPoolId) {
|
||||||
|
return POOL_PARAMETER.get(threadPoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register dynamic thread pool parameters.
|
||||||
|
*
|
||||||
|
* @param threadPoolId thread-pool id
|
||||||
|
* @param threadPoolParameter thread-pool parameter
|
||||||
|
*/
|
||||||
|
public static void registerPoolParameter(String threadPoolId, ThreadPoolParameter threadPoolParameter) {
|
||||||
|
POOL_PARAMETER.put(threadPoolId, threadPoolParameter);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cn.hippo4j.threadpool.dynamic.mode.config.refresher.event;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
|
||||||
|
import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum;
|
||||||
|
import cn.hippo4j.common.executor.support.ResizableCapacityLinkedBlockingQueue;
|
||||||
|
import cn.hippo4j.common.extension.design.Observer;
|
||||||
|
import cn.hippo4j.common.extension.design.ObserverMessage;
|
||||||
|
import cn.hippo4j.common.model.executor.ExecutorProperties;
|
||||||
|
import cn.hippo4j.common.toolkit.ThreadPoolExecutorUtil;
|
||||||
|
import cn.hippo4j.threadpool.dynamic.core.executor.manage.GlobalThreadPoolManage;
|
||||||
|
import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties;
|
||||||
|
import cn.hippo4j.threadpool.dynamic.core.executor.manage.GlobalConfigThreadPoolManage;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.RejectedExecutionHandler;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_THREAD_POOL_TEXT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic thread-pool refresh listener.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DynamicThreadPoolRefreshListener implements Observer<BootstrapConfigProperties> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(ObserverMessage<BootstrapConfigProperties> observerMessage) {
|
||||||
|
BootstrapConfigProperties bindableConfigProperties = observerMessage.message();
|
||||||
|
List<ExecutorProperties> executors = bindableConfigProperties.getExecutors();
|
||||||
|
for (ExecutorProperties properties : executors) {
|
||||||
|
String threadPoolId = properties.getThreadPoolId();
|
||||||
|
dynamicRefreshPool(threadPoolId, properties);
|
||||||
|
ExecutorProperties beforeProperties = GlobalConfigThreadPoolManage.getProperties(properties.getThreadPoolId());
|
||||||
|
log.info(CHANGE_THREAD_POOL_TEXT,
|
||||||
|
threadPoolId,
|
||||||
|
String.format(CHANGE_DELIMITER, beforeProperties.getCorePoolSize(), properties.getCorePoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, beforeProperties.getMaximumPoolSize(), properties.getMaximumPoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, beforeProperties.getQueueCapacity(), properties.getQueueCapacity()),
|
||||||
|
String.format(CHANGE_DELIMITER, beforeProperties.getKeepAliveTime(), properties.getKeepAliveTime()),
|
||||||
|
String.format(CHANGE_DELIMITER, beforeProperties.getRejectedHandler(), properties.getRejectedHandler()),
|
||||||
|
String.format(CHANGE_DELIMITER, beforeProperties.getAllowCoreThreadTimeOut(), properties.getAllowCoreThreadTimeOut()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic refresh pool.
|
||||||
|
*
|
||||||
|
* @param threadPoolId
|
||||||
|
* @param properties
|
||||||
|
*/
|
||||||
|
private void dynamicRefreshPool(String threadPoolId, ExecutorProperties properties) {
|
||||||
|
ExecutorProperties beforeProperties = GlobalConfigThreadPoolManage.getProperties(properties.getThreadPoolId());
|
||||||
|
ThreadPoolExecutor executor = GlobalThreadPoolManage.getExecutorService(threadPoolId);
|
||||||
|
if (properties.getMaximumPoolSize() != null && properties.getCorePoolSize() != null) {
|
||||||
|
ThreadPoolExecutorUtil.safeSetPoolSize(executor, properties.getCorePoolSize(), properties.getMaximumPoolSize());
|
||||||
|
} else {
|
||||||
|
if (properties.getMaximumPoolSize() != null) {
|
||||||
|
executor.setMaximumPoolSize(properties.getMaximumPoolSize());
|
||||||
|
}
|
||||||
|
if (properties.getCorePoolSize() != null) {
|
||||||
|
executor.setCorePoolSize(properties.getCorePoolSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (properties.getAllowCoreThreadTimeOut() != null && !Objects.equals(beforeProperties.getAllowCoreThreadTimeOut(), properties.getAllowCoreThreadTimeOut())) {
|
||||||
|
executor.allowCoreThreadTimeOut(properties.getAllowCoreThreadTimeOut());
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
if (properties.getExecuteTimeOut() != null && !Objects.equals(beforeProperties.getExecuteTimeOut(), properties.getExecuteTimeOut())) {
|
||||||
|
// if (executor instanceof DynamicThreadPoolExecutor) {
|
||||||
|
// ((DynamicThreadPoolExecutor) executor).setExecuteTimeOut(properties.getExecuteTimeOut());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if (properties.getRejectedHandler() != null && !Objects.equals(beforeProperties.getRejectedHandler(), properties.getRejectedHandler())) {
|
||||||
|
RejectedExecutionHandler rejectedExecutionHandler = RejectedPolicyTypeEnum.createPolicy(properties.getRejectedHandler());
|
||||||
|
executor.setRejectedExecutionHandler(rejectedExecutionHandler);
|
||||||
|
}
|
||||||
|
if (properties.getKeepAliveTime() != null && !Objects.equals(beforeProperties.getKeepAliveTime(), properties.getKeepAliveTime())) {
|
||||||
|
executor.setKeepAliveTime(properties.getKeepAliveTime(), TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
if (properties.getQueueCapacity() != null && !Objects.equals(beforeProperties.getQueueCapacity(), properties.getQueueCapacity())
|
||||||
|
&& Objects.equals(BlockingQueueTypeEnum.RESIZABLE_LINKED_BLOCKING_QUEUE.getName(), executor.getQueue().getClass().getSimpleName())) {
|
||||||
|
if (executor.getQueue() instanceof ResizableCapacityLinkedBlockingQueue) {
|
||||||
|
ResizableCapacityLinkedBlockingQueue<?> queue = (ResizableCapacityLinkedBlockingQueue<?>) executor.getQueue();
|
||||||
|
queue.setCapacity(properties.getQueueCapacity());
|
||||||
|
} else {
|
||||||
|
log.warn("The queue length cannot be modified. Queue type mismatch. Current queue type: {}", executor.getQueue().getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/refresher/SpringBoot1xBootstrapConfigPropertiesBinderAdapt.java → starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/refresher/SpringBoot1xBootstrapConfigPropertiesBinderAdapter.java
4
starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/refresher/SpringBoot1xBootstrapConfigPropertiesBinderAdapt.java → starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/refresher/SpringBoot1xBootstrapConfigPropertiesBinderAdapter.java
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.config.springboot.starter.parser;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config file type enum
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
public enum ConfigFileTypeEnum {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PROPERTIES
|
|
||||||
*/
|
|
||||||
PROPERTIES("properties"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XML
|
|
||||||
*/
|
|
||||||
XML("xml"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON
|
|
||||||
*/
|
|
||||||
JSON("json"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* YML
|
|
||||||
*/
|
|
||||||
YML("yml"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* YAML
|
|
||||||
*/
|
|
||||||
YAML("yaml"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TXT
|
|
||||||
*/
|
|
||||||
TXT("txt");
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
ConfigFileTypeEnum(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConfigFileTypeEnum of(String value) {
|
|
||||||
for (ConfigFileTypeEnum typeEnum : ConfigFileTypeEnum.values()) {
|
|
||||||
if (typeEnum.value.equals(value)) {
|
|
||||||
return typeEnum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PROPERTIES;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.config.springboot.starter.parser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config parser.
|
|
||||||
*/
|
|
||||||
public interface ConfigParser {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Supports.
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
boolean supports(ConfigFileTypeEnum type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do parse.
|
|
||||||
*
|
|
||||||
* @param content
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
Map<Object, Object> doParse(String content) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get config file types.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
List<ConfigFileTypeEnum> getConfigFileTypes();
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.config.springboot.starter.parser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ServiceLoader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config parser handler.
|
|
||||||
*/
|
|
||||||
public final class ConfigParserHandler {
|
|
||||||
|
|
||||||
private static final List<ConfigParser> PARSERS = new ArrayList<>();
|
|
||||||
|
|
||||||
private ConfigParserHandler() {
|
|
||||||
ServiceLoader<ConfigParser> loader = ServiceLoader.load(ConfigParser.class);
|
|
||||||
for (ConfigParser configParser : loader) {
|
|
||||||
PARSERS.add(configParser);
|
|
||||||
}
|
|
||||||
PARSERS.add(new PropertiesConfigParser());
|
|
||||||
PARSERS.add(new YamlConfigParser());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Object, Object> parseConfig(String content, ConfigFileTypeEnum type) throws IOException {
|
|
||||||
for (ConfigParser parser : PARSERS) {
|
|
||||||
if (parser.supports(type)) {
|
|
||||||
return parser.doParse(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConfigParserHandler getInstance() {
|
|
||||||
return ConfigParserHandlerHolder.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config Parser Handler Holder
|
|
||||||
*/
|
|
||||||
private static class ConfigParserHandlerHolder {
|
|
||||||
|
|
||||||
private static final ConfigParserHandler INSTANCE = new ConfigParserHandler();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.config.springboot.starter.parser;
|
|
||||||
|
|
||||||
import cn.hippo4j.common.toolkit.CollectionUtil;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Properties config parser.
|
|
||||||
*/
|
|
||||||
public class PropertiesConfigParser extends AbstractConfigParser {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Object, Object> doParse(String content) throws IOException {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.load(new StringReader(content));
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ConfigFileTypeEnum> getConfigFileTypes() {
|
|
||||||
return CollectionUtil.newArrayList(ConfigFileTypeEnum.PROPERTIES);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.config.springboot.starter.parser;
|
|
||||||
|
|
||||||
import cn.hippo4j.common.toolkit.CollectionUtil;
|
|
||||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yaml config parser.
|
|
||||||
*/
|
|
||||||
public class YamlConfigParser extends AbstractConfigParser {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Object, Object> doParse(String content) {
|
|
||||||
if (StringUtils.isEmpty(content)) {
|
|
||||||
return new HashMap<>(1);
|
|
||||||
}
|
|
||||||
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
|
|
||||||
yamlPropertiesFactoryBean.setResources(new ByteArrayResource(content.getBytes()));
|
|
||||||
return yamlPropertiesFactoryBean.getObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ConfigFileTypeEnum> getConfigFileTypes() {
|
|
||||||
return CollectionUtil.newArrayList(ConfigFileTypeEnum.YML, ConfigFileTypeEnum.YAML);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,177 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.core.executor.support;
|
|
||||||
|
|
||||||
import cn.hippo4j.core.executor.plugin.impl.ThreadPoolExecutorShutdownPlugin;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.RejectedExecutionHandler;
|
|
||||||
import java.util.concurrent.RunnableFuture;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dynamic executor configuration support.
|
|
||||||
*
|
|
||||||
* @deprecated use {@link ThreadPoolExecutorShutdownPlugin} to get thread-pool shutdown support
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Slf4j
|
|
||||||
public abstract class AbstractDynamicExecutorSupport extends ThreadPoolExecutor implements InitializingBean, DisposableBean {
|
|
||||||
|
|
||||||
private String threadPoolId;
|
|
||||||
|
|
||||||
private ExecutorService executor;
|
|
||||||
|
|
||||||
private long awaitTerminationMillis;
|
|
||||||
|
|
||||||
private boolean waitForTasksToCompleteOnShutdown;
|
|
||||||
|
|
||||||
public AbstractDynamicExecutorSupport(int corePoolSize,
|
|
||||||
int maximumPoolSize,
|
|
||||||
long keepAliveTime,
|
|
||||||
TimeUnit unit,
|
|
||||||
boolean waitForTasksToCompleteOnShutdown,
|
|
||||||
long awaitTerminationMillis,
|
|
||||||
BlockingQueue<Runnable> workQueue,
|
|
||||||
String threadPoolId,
|
|
||||||
ThreadFactory threadFactory,
|
|
||||||
RejectedExecutionHandler handler) {
|
|
||||||
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
|
|
||||||
this.threadPoolId = threadPoolId;
|
|
||||||
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
|
|
||||||
this.awaitTerminationMillis = awaitTerminationMillis;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the target {@link java.util.concurrent.ExecutorService} instance.
|
|
||||||
* Called by {@code afterPropertiesSet}.
|
|
||||||
*
|
|
||||||
* @return a new ExecutorService instance
|
|
||||||
* @see #afterPropertiesSet()
|
|
||||||
*/
|
|
||||||
protected abstract ExecutorService initializeExecutor();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls {@code initialize()} after the container applied all property values.
|
|
||||||
*
|
|
||||||
* @see #initialize()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void afterPropertiesSet() {
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls {@code shutdown} when the BeanFactory destroys.
|
|
||||||
* the task executor instance.
|
|
||||||
*
|
|
||||||
* @see #shutdown()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
shutdownSupport();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the ExecutorService.
|
|
||||||
*/
|
|
||||||
public void initialize() {
|
|
||||||
if (log.isInfoEnabled()) {
|
|
||||||
log.info("Initializing ExecutorService" + (this.threadPoolId != null ? " '" + this.threadPoolId + "'" : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.executor = initializeExecutor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set support param.
|
|
||||||
*
|
|
||||||
* @param awaitTerminationMillis
|
|
||||||
* @param waitForTasksToCompleteOnShutdown
|
|
||||||
*/
|
|
||||||
public void setSupportParam(long awaitTerminationMillis, boolean waitForTasksToCompleteOnShutdown) {
|
|
||||||
this.awaitTerminationMillis = awaitTerminationMillis;
|
|
||||||
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a shutdown on the underlying ExecutorService.
|
|
||||||
*
|
|
||||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
|
||||||
* @see java.util.concurrent.ExecutorService#shutdownNow()
|
|
||||||
*/
|
|
||||||
public void shutdownSupport() {
|
|
||||||
if (log.isInfoEnabled()) {
|
|
||||||
log.info("Shutting down ExecutorService" + (this.threadPoolId != null ? " '" + this.threadPoolId + "'" : ""));
|
|
||||||
}
|
|
||||||
if (this.executor != null) {
|
|
||||||
if (this.waitForTasksToCompleteOnShutdown) {
|
|
||||||
this.executor.shutdown();
|
|
||||||
} else {
|
|
||||||
for (Runnable remainingTask : this.executor.shutdownNow()) {
|
|
||||||
cancelRemainingTask(remainingTask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
awaitTerminationIfNecessary(this.executor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel the given remaining task which never commended execution,
|
|
||||||
* as returned from {@link ExecutorService#shutdownNow()}.
|
|
||||||
*
|
|
||||||
* @param task the task to cancel (typically a {@link RunnableFuture})
|
|
||||||
* @see #shutdown()
|
|
||||||
* @see RunnableFuture#cancel(boolean)
|
|
||||||
* @since 5.0.5
|
|
||||||
*/
|
|
||||||
protected void cancelRemainingTask(Runnable task) {
|
|
||||||
if (task instanceof Future) {
|
|
||||||
((Future<?>) task).cancel(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for the executor to terminate, according to the value of the.
|
|
||||||
*/
|
|
||||||
private void awaitTerminationIfNecessary(ExecutorService executor) {
|
|
||||||
if (this.awaitTerminationMillis > 0) {
|
|
||||||
try {
|
|
||||||
if (!executor.awaitTermination(this.awaitTerminationMillis, TimeUnit.MILLISECONDS)) {
|
|
||||||
if (log.isWarnEnabled()) {
|
|
||||||
log.warn("Timed out while waiting for executor"
|
|
||||||
+ (this.threadPoolId != null ? " '" + this.threadPoolId + "'" : "") + " to terminate.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
if (log.isWarnEnabled()) {
|
|
||||||
log.warn("Interrupted while waiting for executor"
|
|
||||||
+ (this.threadPoolId != null ? " '" + this.threadPoolId + "'" : "") + " to terminate.");
|
|
||||||
}
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.core.executor.support;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
|
||||||
import java.util.concurrent.RejectedExecutionHandler;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fast thread-pool executor.
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class FastThreadPoolExecutor extends ThreadPoolExecutorTemplate {
|
|
||||||
|
|
||||||
public FastThreadPoolExecutor(int corePoolSize,
|
|
||||||
int maximumPoolSize,
|
|
||||||
long keepAliveTime,
|
|
||||||
TimeUnit unit,
|
|
||||||
TaskQueue<Runnable> workQueue,
|
|
||||||
ThreadFactory threadFactory,
|
|
||||||
RejectedExecutionHandler handler) {
|
|
||||||
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Statistics on the number of tasks submitted by the fast consumption thread pool
|
|
||||||
*/
|
|
||||||
private final AtomicInteger submittedTaskCount = new AtomicInteger(0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get submitted task count.
|
|
||||||
*
|
|
||||||
* @return submitted task count
|
|
||||||
*/
|
|
||||||
public int getSubmittedTaskCount() {
|
|
||||||
return submittedTaskCount.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void afterExecute(Runnable r, Throwable t) {
|
|
||||||
submittedTaskCount.decrementAndGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Runnable command) {
|
|
||||||
submittedTaskCount.incrementAndGet();
|
|
||||||
try {
|
|
||||||
super.execute(command);
|
|
||||||
} catch (RejectedExecutionException rx) {
|
|
||||||
final TaskQueue queue = (TaskQueue) super.getQueue();
|
|
||||||
try {
|
|
||||||
if (!queue.retryOffer(command, 0, TimeUnit.MILLISECONDS)) {
|
|
||||||
submittedTaskCount.decrementAndGet();
|
|
||||||
throw new RejectedExecutionException("The blocking queue capacity is full.", rx);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException x) {
|
|
||||||
submittedTaskCount.decrementAndGet();
|
|
||||||
throw new RejectedExecutionException(x);
|
|
||||||
}
|
|
||||||
} catch (Exception t) {
|
|
||||||
submittedTaskCount.decrementAndGet();
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.core.executor.support;
|
|
||||||
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Task queue.
|
|
||||||
*/
|
|
||||||
public class TaskQueue<R extends Runnable> extends LinkedBlockingQueue<Runnable> {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -2635853580887179627L;
|
|
||||||
|
|
||||||
@Setter
|
|
||||||
private FastThreadPoolExecutor executor;
|
|
||||||
|
|
||||||
public TaskQueue(int capacity) {
|
|
||||||
super(capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean offer(Runnable runnable) {
|
|
||||||
int currentPoolThreadSize = executor.getPoolSize();
|
|
||||||
// If a core thread is idle, add the task to the blocking queue, and the core thread will process the task.
|
|
||||||
if (executor.getSubmittedTaskCount() < currentPoolThreadSize) {
|
|
||||||
return super.offer(runnable);
|
|
||||||
}
|
|
||||||
// The current number of threads in the thread pool is less than the maximum number of threads, and returns false.
|
|
||||||
// According to the thread pool source code, non-core threads will be created.
|
|
||||||
if (currentPoolThreadSize < executor.getMaximumPoolSize()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// If the current thread pool number is greater than the maximum number of threads, the task is added to the blocking queue.
|
|
||||||
return super.offer(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retry offer.
|
|
||||||
*
|
|
||||||
* @param runnable submit thread pool task
|
|
||||||
* @param timeout how long to wait before giving up, in units of
|
|
||||||
* {@code unit}
|
|
||||||
* @param unit a {@code TimeUnit} determining how to interpret the
|
|
||||||
* {@code timeout} parameter
|
|
||||||
* @return
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
|
||||||
public boolean retryOffer(Runnable runnable, long timeout, TimeUnit unit) throws InterruptedException {
|
|
||||||
if (executor.isShutdown()) {
|
|
||||||
throw new RejectedExecutionException("Actuator closed!");
|
|
||||||
}
|
|
||||||
return super.offer(runnable, timeout, unit);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.core.executor.support;
|
|
||||||
|
|
||||||
import cn.hippo4j.common.toolkit.ArrayUtil;
|
|
||||||
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.RejectedExecutionHandler;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ThreadPool executor template.
|
|
||||||
*/
|
|
||||||
public class ThreadPoolExecutorTemplate extends ThreadPoolExecutor {
|
|
||||||
|
|
||||||
public ThreadPoolExecutorTemplate(int corePoolSize,
|
|
||||||
int maximumPoolSize,
|
|
||||||
long keepAliveTime,
|
|
||||||
TimeUnit unit,
|
|
||||||
BlockingQueue<Runnable> workQueue,
|
|
||||||
ThreadFactory threadFactory,
|
|
||||||
RejectedExecutionHandler handler) {
|
|
||||||
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final Runnable command) {
|
|
||||||
super.execute(wrap(command, clientTrace()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Future<?> submit(final Runnable task) {
|
|
||||||
return super.submit(wrap(task, clientTrace()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> Future<T> submit(final Callable<T> task) {
|
|
||||||
return super.submit(wrap(task, clientTrace()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client trace.
|
|
||||||
*
|
|
||||||
* @return exception
|
|
||||||
*/
|
|
||||||
private Exception clientTrace() {
|
|
||||||
return new Exception("Tread task root stack trace.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapping thread pool tasks.
|
|
||||||
*
|
|
||||||
* @param task task
|
|
||||||
* @param clientStack client stack
|
|
||||||
* @return wrapped runnable
|
|
||||||
*/
|
|
||||||
private Runnable wrap(final Runnable task, final Exception clientStack) {
|
|
||||||
return () -> {
|
|
||||||
try {
|
|
||||||
task.run();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.setStackTrace(ArrayUtil.addAll(clientStack.getStackTrace(), e.getStackTrace()));
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapping thread pool tasks.
|
|
||||||
*
|
|
||||||
* @param task task
|
|
||||||
* @param clientStack client stack
|
|
||||||
* @param <T> computed result
|
|
||||||
* @return wrapped runnable
|
|
||||||
*/
|
|
||||||
private <T> Callable<T> wrap(final Callable<T> task, final Exception clientStack) {
|
|
||||||
return () -> {
|
|
||||||
try {
|
|
||||||
return task.call();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.setStackTrace(ArrayUtil.addAll(clientStack.getStackTrace(), e.getStackTrace()));
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cn.hippo4j.core.executor.support;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test for {@link FastThreadPoolExecutor}
|
|
||||||
*/
|
|
||||||
public class FastThreadPoolExecutorTest {
|
|
||||||
|
|
||||||
private final static int corePoolSize = 1;
|
|
||||||
|
|
||||||
private final static int capacity = 1;
|
|
||||||
|
|
||||||
private final TaskQueue<Runnable> taskQueue = new TaskQueue<>(capacity);
|
|
||||||
|
|
||||||
private final FastThreadPoolExecutor fastThreadPoolExecutor = new FastThreadPoolExecutor(corePoolSize,
|
|
||||||
corePoolSize,
|
|
||||||
10,
|
|
||||||
TimeUnit.SECONDS,
|
|
||||||
taskQueue,
|
|
||||||
Thread::new,
|
|
||||||
new ThreadPoolExecutor.AbortPolicy());
|
|
||||||
|
|
||||||
{
|
|
||||||
taskQueue.setExecutor(fastThreadPoolExecutor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSubmittedTaskCount() {
|
|
||||||
fastThreadPoolExecutor.execute(() -> {
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(2);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
Assertions.assertEquals(1, fastThreadPoolExecutor.getSubmittedTaskCount());
|
|
||||||
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
Assertions.assertEquals(0, fastThreadPoolExecutor.getSubmittedTaskCount());
|
|
||||||
|
|
||||||
// exception
|
|
||||||
int expected = 0;
|
|
||||||
for (int i = 0; i <= (corePoolSize + capacity); i++) {
|
|
||||||
expected++;
|
|
||||||
try {
|
|
||||||
fastThreadPoolExecutor.execute(() -> {
|
|
||||||
synchronized (fastThreadPoolExecutor) {
|
|
||||||
try {
|
|
||||||
fastThreadPoolExecutor.wait();
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
expected--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
Assertions.assertEquals(expected, fastThreadPoolExecutor.getSubmittedTaskCount());
|
|
||||||
|
|
||||||
synchronized (fastThreadPoolExecutor) {
|
|
||||||
fastThreadPoolExecutor.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue