From b43c90bd5f585e15f4aab66b29741bc06f0ea452 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=88=90=E5=85=B4?=
<49221670+Createsequence@users.noreply.github.com>
Date: Tue, 1 Nov 2022 18:43:49 +0800
Subject: [PATCH] refactor: Extract the logic about calculating task execution
time to superclass (#879) (#882)
---
.../plugin/impl/AbstractTaskTimerPlugin.java | 88 +++++++++++++++++++
.../plugin/impl/TaskTimeRecordPlugin.java | 60 ++-----------
.../impl/TaskTimeoutNotifyAlarmPlugin.java | 33 ++++---
3 files changed, 113 insertions(+), 68 deletions(-)
create mode 100644 hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/AbstractTaskTimerPlugin.java
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/AbstractTaskTimerPlugin.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/AbstractTaskTimerPlugin.java
new file mode 100644
index 00000000..4a42fef3
--- /dev/null
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/AbstractTaskTimerPlugin.java
@@ -0,0 +1,88 @@
+/*
+ * 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.plugin.impl;
+
+import cn.hippo4j.core.executor.ExtensibleThreadPoolExecutor;
+import cn.hippo4j.core.plugin.ExecuteAwarePlugin;
+import cn.hippo4j.core.toolkit.SystemClock;
+
+import java.util.Optional;
+
+/**
+ *
An abstract task execution time recording plugin
+ * for thread-safe statistics the execution time of tasks.
+ *
+ *
Must override {@link #processTaskTime} to define the processing logic for task execution time.
+ * Default time precision is milliseconds, may override {@link #currentTime} to redefine the time precision.
+ *
+ * @see TaskTimeRecordPlugin
+ * @see TaskTimeoutNotifyAlarmPlugin
+ */
+public abstract class AbstractTaskTimerPlugin implements ExecuteAwarePlugin {
+
+ /**
+ * start times of executed tasks
+ */
+ private final ThreadLocal startTimes = new ThreadLocal<>();
+
+ /**
+ * Record the time when the worker thread starts executing the task.
+ *
+ * @param thread thread of executing task
+ * @param runnable task
+ * @see ExtensibleThreadPoolExecutor#beforeExecute
+ */
+ @Override
+ public final void beforeExecute(Thread thread, Runnable runnable) {
+ startTimes.set(currentTime());
+ }
+
+ /**
+ * Record the total time for the worker thread to complete the task, and update the time record.
+ *
+ * @param runnable runnable
+ * @param throwable exception thrown during execution
+ */
+ @Override
+ public final void afterExecute(Runnable runnable, Throwable throwable) {
+ try {
+ Optional.ofNullable(startTimes.get())
+ .map(startTime -> currentTime() - startTime)
+ .ifPresent(this::processTaskTime);
+ } finally {
+ startTimes.remove();
+ }
+ }
+
+ /**
+ * Get the current time.
+ *
+ * @return current time
+ */
+ protected long currentTime() {
+ return SystemClock.now();
+ }
+
+ /**
+ * Processing the execution time of the task.
+ *
+ * @param taskExecuteTime execute time of task
+ */
+ protected abstract void processTaskTime(long taskExecuteTime);
+
+}
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeRecordPlugin.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeRecordPlugin.java
index 3ce5c5ad..0bb029c2 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeRecordPlugin.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeRecordPlugin.java
@@ -17,25 +17,19 @@
package cn.hippo4j.core.plugin.impl;
-import cn.hippo4j.core.executor.ExtensibleThreadPoolExecutor;
-import cn.hippo4j.core.plugin.ExecuteAwarePlugin;
import cn.hippo4j.core.plugin.PluginRuntime;
-import cn.hippo4j.core.toolkit.SystemClock;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
-import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Record task execution time indicator.
- *
- * @see TaskTimeoutNotifyAlarmPlugin
*/
@RequiredArgsConstructor
-public class TaskTimeRecordPlugin implements ExecuteAwarePlugin {
+public class TaskTimeRecordPlugin extends AbstractTaskTimerPlugin {
public static final String PLUGIN_NAME = "task-time-record-plugin";
@@ -74,23 +68,6 @@ public class TaskTimeRecordPlugin implements ExecuteAwarePlugin {
return PLUGIN_NAME;
}
- /**
- * start times of executed tasks
- */
- private final ThreadLocal startTimes = new ThreadLocal<>();
-
- /**
- * Record the time when the worker thread starts executing the task.
- *
- * @param thread thread of executing task
- * @param runnable task
- * @see ExtensibleThreadPoolExecutor#beforeExecute
- */
- @Override
- public void beforeExecute(Thread thread, Runnable runnable) {
- startTimes.set(SystemClock.now());
- }
-
/**
* Get plugin runtime info.
*
@@ -107,44 +84,25 @@ public class TaskTimeRecordPlugin implements ExecuteAwarePlugin {
.addInfo("avgTaskTime", summary.getAvgTaskTimeMillis() + "ms");
}
- /**
- * Record the total time for the worker thread to complete the task, and update the time record.
- *
- * @param runnable runnable
- * @param throwable exception thrown during execution
- */
- @Override
- public void afterExecute(Runnable runnable, Throwable throwable) {
- try {
- Long startTime = startTimes.get();
- if (Objects.isNull(startTime)) {
- return;
- }
- long executeTime = SystemClock.now() - startTime;
- recordTaskTime(executeTime);
- } finally {
- startTimes.remove();
- }
- }
-
/**
* Refresh time indicators of the current instance.
*
- * @param taskExecutionTime millisecond
+ * @param taskExecuteTime execute time of task
*/
- protected void recordTaskTime(long taskExecutionTime) {
+ @Override
+ protected void processTaskTime(long taskExecuteTime) {
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
if (taskCount == 0) {
- maxTaskTimeMillis = taskExecutionTime;
- minTaskTimeMillis = taskExecutionTime;
+ maxTaskTimeMillis = taskExecuteTime;
+ minTaskTimeMillis = taskExecuteTime;
} else {
- maxTaskTimeMillis = Math.max(taskExecutionTime, maxTaskTimeMillis);
- minTaskTimeMillis = Math.min(taskExecutionTime, minTaskTimeMillis);
+ maxTaskTimeMillis = Math.max(taskExecuteTime, maxTaskTimeMillis);
+ minTaskTimeMillis = Math.min(taskExecuteTime, minTaskTimeMillis);
}
taskCount = taskCount + 1;
- totalTaskTimeMillis += taskExecutionTime;
+ totalTaskTimeMillis += taskExecuteTime;
} finally {
writeLock.unlock();
}
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java
index 12e522db..4a566f17 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java
@@ -27,11 +27,10 @@ import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;
/**
- * Record task execution time indicator,
- * and send alarm notification when the execution time exceeds the threshold.
+ * Send alarm notification when the execution time exceeds the threshold.
*/
@AllArgsConstructor
-public class TaskTimeoutNotifyAlarmPlugin extends TaskTimeRecordPlugin {
+public class TaskTimeoutNotifyAlarmPlugin extends AbstractTaskTimerPlugin {
public static final String PLUGIN_NAME = "task-timeout-notify-alarm-plugin";
@@ -40,6 +39,15 @@ public class TaskTimeoutNotifyAlarmPlugin extends TaskTimeRecordPlugin {
*/
private final String threadPoolId;
+ @Getter
+ @Setter
+ private Long executeTimeOut;
+
+ /**
+ * thread-pool
+ */
+ private final ThreadPoolExecutor threadPoolExecutor;
+
/**
* Get id.
*
@@ -50,30 +58,21 @@ public class TaskTimeoutNotifyAlarmPlugin extends TaskTimeRecordPlugin {
return PLUGIN_NAME;
}
- @Getter
- @Setter
- private Long executeTimeOut;
-
- /**
- * thread-pool
- */
- private final ThreadPoolExecutor threadPoolExecutor;
-
/**
* Check whether the task execution time exceeds {@link #executeTimeOut},
* if it exceeds this time, send an alarm notification.
*
- * @param executeTime executeTime in nanosecond
+ * @param taskExecuteTime execute time of task
*/
@Override
- protected void recordTaskTime(long executeTime) {
- super.recordTaskTime(executeTime);
- if (executeTime <= executeTimeOut) {
+ protected void processTaskTime(long taskExecuteTime) {
+ if (taskExecuteTime <= executeTimeOut) {
return;
}
Optional.ofNullable(ApplicationContextHolder.getInstance())
.map(context -> context.getBean(ThreadPoolNotifyAlarmHandler.class))
.ifPresent(handler -> handler.asyncSendExecuteTimeOutAlarm(
- threadPoolId, executeTime, executeTimeOut, threadPoolExecutor));
+ threadPoolId, taskExecuteTime, executeTimeOut, threadPoolExecutor));
}
+
}