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