diff --git a/minigame-demo-ddd/src/main/java/cc/magicjson/minigame/demo/ddd/infrastructure/config/EventConfig.java b/minigame-demo-ddd/src/main/java/cc/magicjson/minigame/demo/ddd/infrastructure/config/EventConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..b995070a4167a028776d0b5c298f056788bf70c9
--- /dev/null
+++ b/minigame-demo-ddd/src/main/java/cc/magicjson/minigame/demo/ddd/infrastructure/config/EventConfig.java
@@ -0,0 +1,16 @@
+package cc.magicjson.minigame.demo.ddd.infrastructure.config;
+
+import cc.magicjson.minigame.demo.ddd.infrastructure.event.AntiCorruptionDomainEventPublisher;
+import cc.magicjson.minigame.demo.ddd.infrastructure.event.GameEventListener;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class EventConfig {
+ private final AntiCorruptionDomainEventPublisher eventPublisher;
+ private final GameEventListener gameEventListener;
+
+ public EventConfig(AntiCorruptionDomainEventPublisher eventPublisher, GameEventListener gameEventListener) {
+ this.eventPublisher = eventPublisher;
+ this.gameEventListener = gameEventListener;
+ }
+}
\ No newline at end of file
diff --git a/quick-landing/dynamic-priority-executors/pom.xml b/quick-landing/dynamic-priority-executors/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e8eae5a8d865b02f32f59ef0e86a9565ed9bdf5a
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/pom.xml
@@ -0,0 +1,31 @@
+
+ 4.0.0
+
+ cc.magicjson
+ quick-landing
+ ${revision}
+ ../pom.xml
+
+
+ dynamic-priority-executors
+ jar
+
+ dynamic-priority-executors
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
diff --git a/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/core/DynamicPriorityThreadPool.java b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/core/DynamicPriorityThreadPool.java
new file mode 100644
index 0000000000000000000000000000000000000000..640e7aedaf7e07e5b0dbcf73463672fc242776dd
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/core/DynamicPriorityThreadPool.java
@@ -0,0 +1,207 @@
+package cc.magicjson.concurrent.priority.core;
+
+import cc.magicjson.concurrent.priority.task.*;
+import jakarta.validation.constraints.NotNull;
+
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 动态优先级线程池,扩展了ThreadPoolExecutor,实现了自动关闭功能。
+ * 这个线程池能够根据任务类型动态调整执行优先级,并保证最小数量的线程用于处理轻量级任务。
+ */
+public class DynamicPriorityThreadPool extends ThreadPoolExecutor implements AutoCloseable {
+
+ // 追踪当前正在执行轻量级任务的线程数
+ private final AtomicInteger lightTaskThreads = new AtomicInteger(0);
+ // 保证处理轻量级任务的最小线程数
+ private final int minLightTaskThreads;
+ // 用于分类提交的任务
+ private final TaskClassifier taskClassifier;
+
+ /**
+ * 构造函数
+ * @param corePoolSize 核心线程数
+ * @param maximumPoolSize 最大线程数
+ * @param keepAliveTime 空闲线程存活时间
+ * @param unit 时间单位
+ * @param workQueue 工作队列
+ * @param threadFactory 线程工厂
+ * @param handler 拒绝策略
+ * @param minLightTaskThreads 最小轻量级任务线程数
+ * @param taskClassifier 任务分类器
+ */
+ public DynamicPriorityThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit,
+ @NotNull BlockingQueue workQueue, @NotNull ThreadFactory threadFactory,
+ @NotNull RejectedExecutionHandler handler, int minLightTaskThreads,
+ @NotNull TaskClassifier taskClassifier) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
+ this.minLightTaskThreads = minLightTaskThreads;
+ this.taskClassifier = taskClassifier;
+ }
+
+ /**
+ * 在任务执行前调用,用于追踪轻量级任务的执行情况
+ */
+ @Override
+ protected void beforeExecute(@NotNull Thread t, @NotNull Runnable r) {
+ super.beforeExecute(t, r);
+ if (r instanceof PriorityTask> task && task.getTaskType().isLightWeight()) {
+ lightTaskThreads.incrementAndGet();
+ }
+ }
+
+ /**
+ * 在任务执行后调用,用于更新轻量级任务的计数
+ */
+ @Override
+ protected void afterExecute(@NotNull Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+ if (r instanceof PriorityTask> task && task.getTaskType().isLightWeight()) {
+ lightTaskThreads.decrementAndGet();
+ }
+ }
+
+ /**
+ * 执行提交的任务,确保轻量级任务得到优先处理
+ */
+ @Override
+ public void execute(Runnable command) {
+ PriorityTask> task;
+ if (command instanceof PriorityTask>) {
+ task = (PriorityTask>) command;
+ } else {
+ TaskType taskType = taskClassifier.classifyTask(command);
+ task = PriorityTask.createRunnableTask(command, taskType);
+ }
+
+ if (task.getTaskType().isLightWeight() && lightTaskThreads.get() < minLightTaskThreads) {
+ super.execute(() -> {
+ lightTaskThreads.incrementAndGet();
+ try {
+ task.run();
+ } finally {
+ lightTaskThreads.decrementAndGet();
+ }
+ });
+ } else {
+ super.execute(task);
+ }
+ }
+
+ /**
+ * 创建新的RunnableFuture任务
+ */
+ @NotNull
+ @Override
+ protected RunnableFuture newTaskFor(@NotNull Runnable runnable, T value) {
+ if (runnable instanceof PriorityTask>) {
+ @SuppressWarnings("unchecked")
+ PriorityTask castedTask = (PriorityTask) runnable;
+ return new PriorityFutureTask<>(castedTask);
+ }
+ TaskType taskType = taskClassifier.classifyTask(runnable);
+ return new PriorityFutureTask<>(PriorityTask.createCallableTask(() -> {
+ runnable.run();
+ return value;
+ }, taskType));
+ }
+
+ /**
+ * 创建新的RunnableFuture任务(针对Callable)
+ */
+ @NotNull
+ @Override
+ protected RunnableFuture newTaskFor(@NotNull Callable callable) {
+ if (callable instanceof PriorityTask> priorityTask) {
+ @SuppressWarnings("unchecked")
+ PriorityTask castedTask = (PriorityTask) priorityTask;
+ return new PriorityFutureTask<>(castedTask);
+ }
+ TaskType taskType = taskClassifier.classifyTask(() -> {
+ try {
+ callable.call();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ return new PriorityFutureTask<>(new PriorityTask<>(callable, taskType));
+ }
+
+ /**
+ * 关闭线程池,实现AutoCloseable接口
+ */
+ @Override
+ public void close() {
+ shutdown();
+ try {
+ if (!awaitTermination(60, TimeUnit.SECONDS)) {
+ shutdownNow();
+ if (!awaitTermination(60, TimeUnit.SECONDS)) {
+ System.err.println("Pool did not terminate");
+ }
+ }
+ } catch (InterruptedException ie) {
+ shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ public static class Builder {
+ private int corePoolSize = Runtime.getRuntime().availableProcessors();
+ private int maximumPoolSize = corePoolSize * 2;
+ private long keepAliveTime = 60L;
+ private TimeUnit unit = TimeUnit.SECONDS;
+ private BlockingQueue workQueue = new PriorityBlockingQueue<>();
+ private ThreadFactory threadFactory = Executors.defaultThreadFactory();
+ private RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
+ private int minLightTaskThreads = 1;
+ private TaskClassifier taskClassifier = new DefaultTaskClassifier();
+
+ public Builder corePoolSize(int corePoolSize) {
+ this.corePoolSize = corePoolSize;
+ return this;
+ }
+
+ public Builder maximumPoolSize(int maximumPoolSize) {
+ this.maximumPoolSize = maximumPoolSize;
+ return this;
+ }
+
+ public Builder keepAliveTime(long keepAliveTime, TimeUnit unit) {
+ this.keepAliveTime = keepAliveTime;
+ this.unit = unit;
+ return this;
+ }
+
+ public Builder workQueue(BlockingQueue workQueue) {
+ this.workQueue = workQueue;
+ return this;
+ }
+
+ public Builder threadFactory(ThreadFactory threadFactory) {
+ this.threadFactory = threadFactory;
+ return this;
+ }
+
+ public Builder rejectedExecutionHandler(RejectedExecutionHandler handler) {
+ this.handler = handler;
+ return this;
+ }
+
+ public Builder minLightTaskThreads(int minLightTaskThreads) {
+ this.minLightTaskThreads = minLightTaskThreads;
+ return this;
+ }
+
+ public Builder taskClassifier(TaskClassifier taskClassifier) {
+ this.taskClassifier = taskClassifier;
+ return this;
+ }
+
+ public DynamicPriorityThreadPool build() {
+ return new DynamicPriorityThreadPool(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+ workQueue, threadFactory, handler, minLightTaskThreads, taskClassifier);
+ }
+ }
+}
diff --git a/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/DefaultTaskClassifier.java b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/DefaultTaskClassifier.java
new file mode 100644
index 0000000000000000000000000000000000000000..5780760baeb293dd9873d4feaf0a88e95c405aa5
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/DefaultTaskClassifier.java
@@ -0,0 +1,34 @@
+package cc.magicjson.concurrent.priority.task;
+
+/**
+ * DefaultTaskClassifier 是 TaskClassifier 接口的默认实现。
+ * 它通过检查任务类名中的关键字来确定任务类型。
+ */
+public class DefaultTaskClassifier implements TaskClassifier {
+
+ /**
+ * 根据任务的类名对任务进行分类。
+ *
+ * @param task 需要分类的 Runnable 任务
+ * @return 分类后的 TaskType
+ */
+ @Override
+ public TaskType classifyTask(Runnable task) {
+ // 获取任务的简单类名
+ String taskName = task.getClass().getSimpleName();
+
+ // 根据类名中的关键字判断任务类型
+ if (taskName.contains("FileRead")) {
+ return TaskType.FILE_READ;
+ } else if (taskName.contains("DNS")) {
+ return TaskType.DNS_LOOKUP;
+ } else if (taskName.contains("Database")) {
+ return TaskType.DATABASE_QUERY;
+ } else if (taskName.contains("Network")) {
+ return TaskType.NETWORK_IO;
+ }
+
+ // 如果没有匹配到特定类型,默认为计算任务
+ return TaskType.COMPUTATION;
+ }
+}
diff --git a/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/PriorityFutureTask.java b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/PriorityFutureTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..87b20945388ad0cca88530289251b4a307e78751
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/PriorityFutureTask.java
@@ -0,0 +1,39 @@
+package cc.magicjson.concurrent.priority.task;
+
+import java.util.concurrent.FutureTask;
+
+/**
+ * PriorityFutureTask 类扩展了 FutureTask,并实现了 Comparable 接口。
+ * 这个类用于在线程池中包装 PriorityTask,使其可以根据优先级进行排序。
+ *
+ * @param 任务结果的类型
+ */
+public class PriorityFutureTask extends FutureTask implements Comparable> {
+
+ /**
+ * 被包装的 PriorityTask 实例
+ */
+ private final PriorityTask priorityTask;
+
+ /**
+ * 构造一个新的 PriorityFutureTask
+ *
+ * @param task 要包装的 PriorityTask
+ */
+ public PriorityFutureTask(PriorityTask task) {
+ super(task);
+ this.priorityTask = task;
+ }
+
+ /**
+ * 比较此 PriorityFutureTask 与另一个 PriorityFutureTask 的优先级
+ *
+ * @param o 要比较的其他 PriorityFutureTask
+ * @return 负数表示此任务优先级更高,正数表示其他任务优先级更高,0 表示优先级相同
+ */
+ @Override
+ public int compareTo(PriorityFutureTask o) {
+ // 委托给内部 PriorityTask 的 compareTo 方法
+ return this.priorityTask.compareTo(o.priorityTask);
+ }
+}
diff --git a/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/PriorityTask.java b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/PriorityTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..01381a9f9a7afe489bc7ea5a3f6f48a1732a3b39
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/PriorityTask.java
@@ -0,0 +1,132 @@
+package cc.magicjson.concurrent.priority.task;
+
+import java.util.concurrent.Callable;
+
+
+/**
+ * PriorityTask 类表示一个具有优先级的任务。
+ * 它实现了 Callable 接口,同时也实现了 Comparable 接口以支持优先级比较。
+ *
+ * @param 任务执行结果的类型
+ */
+public class PriorityTask implements Runnable, Callable, Comparable> {
+
+ // 存储 Callable 类型的任务
+ private final Callable task;
+
+ // 任务的类型,用于确定任务的特性(如是否为轻量级任务)
+ private final TaskType taskType;
+
+ // 任务的优先级,数值越小优先级越高
+ private final int priority;
+
+ // 任务创建的时间戳,用于在优先级相同时进行比较
+ private final long creationTime;
+
+ public PriorityTask(Callable task, TaskType taskType) {
+ this.task = task;
+ this.taskType = taskType;
+ this.priority = taskType.getPriority();
+ this.creationTime = System.nanoTime();
+ }
+
+ /**
+ * 实现 Callable 接口的 call 方法
+ *
+ * @return 任务执行的结果
+ * @throws Exception 如果任务执行过程中抛出异常
+ */
+ @Override
+ public V call() throws Exception {
+ return task.call();
+ }
+
+ /**
+ * 实现 Runnable 接口的 run 方法
+ *
+ * @throws Exception 如果任务执行过程中抛出异常
+ */
+ @Override
+ public void run() {
+ try {
+ call();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 获取任务类型
+ *
+ * @return 任务类型
+ */
+ public TaskType getTaskType() {
+ return taskType;
+ }
+
+ /**
+ * 获取任务优先级
+ *
+ * @return 任务优先级
+ */
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * 获取任务创建时间
+ *
+ * @return 任务创建时间(纳秒)
+ */
+ public long getCreationTime() {
+ return creationTime;
+ }
+
+ /**
+ * 实现 Comparable 接口的 compareTo 方法
+ * 首先比较优先级,优先级相同时比较创建时间
+ *
+ * @param other 要比较的其他 PriorityTask
+ * @return 比较结果:负数表示此任务优先级更高,正数表示其他任务优先级更高,0表示优先级相同
+ */
+ @Override
+ public int compareTo(PriorityTask> other) {
+ // 优先级数字越小,优先级越高
+ int priorityCompare = Integer.compare(this.getTaskType().getPriority(), other.getTaskType().getPriority());
+ if (priorityCompare != 0) {
+ return priorityCompare;
+ }
+ // 如果优先级相同,比较创建时间
+ return Long.compare(this.getCreationTime(), other.getCreationTime());
+ }
+
+ /**
+ * 创建 Callable 版本的 PriorityTask 的工厂方法
+ *
+ * @param callable Callable 任务
+ * @param taskType 任务类型
+ * @param Callable 的返回类型
+ * @return 包装了 Callable 的 PriorityTask
+ */
+ public static PriorityTask createCallableTask(Callable callable, TaskType taskType) {
+ return new PriorityTask<>(callable, taskType);
+ }
+
+ /**
+ * 创建 Runnable 版本的 PriorityTask 的工厂方法
+ *
+ * @param runnable Runnable 任务
+ * @param taskType 任务类型
+ * @return 包装了 Runnable 的 PriorityTask
+ */
+ public static PriorityTask createRunnableTask(Runnable runnable, TaskType taskType) {
+ return new PriorityTask<>(() -> {
+ runnable.run();
+ return null;
+ }, taskType);
+ }
+
+ public Callable asCallable() {
+ return this;
+ }
+}
diff --git a/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/TaskClassifier.java b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/TaskClassifier.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ecd96656c7293d27c821e224453de471c120a3e
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/TaskClassifier.java
@@ -0,0 +1,16 @@
+package cc.magicjson.concurrent.priority.task;
+
+/**
+ * TaskClassifier 接口定义了任务分类器的行为。
+ * 实现此接口的类负责将提交的 Runnable 任务分类为预定义的 TaskType。
+ */
+public interface TaskClassifier {
+
+ /**
+ * 对给定的任务进行分类。
+ *
+ * @param task 需要分类的 Runnable 任务
+ * @return 分类后的 TaskType
+ */
+ TaskType classifyTask(Runnable task);
+}
diff --git a/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/TaskType.java b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/TaskType.java
new file mode 100644
index 0000000000000000000000000000000000000000..29025cf7189bddb096b208ca1fae1d51e638fbd2
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/main/java/cc/magicjson/concurrent/priority/task/TaskType.java
@@ -0,0 +1,80 @@
+package cc.magicjson.concurrent.priority.task;
+
+import lombok.Getter;
+
+/**
+ * TaskType 枚举定义了系统中不同类型的任务及其优先级和轻量级标志。
+ * 这个枚举用于在动态优先级线程池中对任务进行分类和优先级排序。
+ */
+public enum TaskType {
+ /**
+ * 文件读取任务
+ * 优先级最高(1),被视为轻量级任务
+ * 通常用于快速的文件I/O操作
+ */
+ FILE_READ(1, true),
+
+ /**
+ * DNS查询任务
+ * 优先级最低(5),不被视为轻量级任务
+ * 用于网络相关的DNS解析操作
+ */
+ DNS_LOOKUP(5, false),
+
+ /**
+ * 数据库查询任务
+ * 优先级中等(3),不被视为轻量级任务
+ * 用于数据库操作,可能涉及复杂查询或事务
+ */
+ DATABASE_QUERY(3, false),
+
+ /**
+ * 计算任务
+ * 优先级较低(4),不被视为轻量级任务
+ * 用于CPU密集型的计算操作
+ */
+ COMPUTATION(4, false),
+
+ /**
+ * 网络I/O任务
+ * 优先级较高(2),不被视为轻量级任务
+ * 用于一般的网络通信操作
+ */
+ NETWORK_IO(2, false);
+
+ /**
+ * 任务的优先级
+ * 数值越小,优先级越高
+ * -- GETTER --
+ * 获取任务的优先级
+ *
+ */
+ @Getter
+ private final int priority;
+
+ /**
+ * 标志是否为轻量级任务
+ * 轻量级任务可能会得到特殊处理,如优先执行
+ */
+ private final boolean isLightWeight;
+
+ /**
+ * TaskType 的构造函数
+ *
+ * @param priority 任务的优先级,数值越小优先级越高
+ * @param isLightWeight 是否为轻量级任务的标志
+ */
+ TaskType(int priority, boolean isLightWeight) {
+ this.priority = priority;
+ this.isLightWeight = isLightWeight;
+ }
+
+ /**
+ * 判断任务是否为轻量级任务
+ *
+ * @return 如果是轻量级任务返回 true,否则返回 false
+ */
+ public boolean isLightWeight() {
+ return isLightWeight;
+ }
+}
diff --git a/quick-landing/dynamic-priority-executors/src/test/java/cc/magicjson/concurrent/priority/test/DynamicPriorityThreadPoolTest.java b/quick-landing/dynamic-priority-executors/src/test/java/cc/magicjson/concurrent/priority/test/DynamicPriorityThreadPoolTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7e343f3c6e6380ee227ad3297c002f97cadeb58
--- /dev/null
+++ b/quick-landing/dynamic-priority-executors/src/test/java/cc/magicjson/concurrent/priority/test/DynamicPriorityThreadPoolTest.java
@@ -0,0 +1,131 @@
+package cc.magicjson.concurrent.priority.test;
+
+import cc.magicjson.concurrent.priority.core.DynamicPriorityThreadPool;
+import cc.magicjson.concurrent.priority.task.PriorityTask;
+import cc.magicjson.concurrent.priority.task.TaskType;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class DynamicPriorityThreadPoolTest {
+
+ private record TaskExecution(TaskType type, Instant startTime, Instant endTime, int executionOrder) {
+ }
+
+ @Test
+ @Timeout(60)
+ public void testTaskPriorities() {
+ try (var pool = new DynamicPriorityThreadPool.Builder()
+ .corePoolSize(2)
+ .maximumPoolSize(4)
+ .minLightTaskThreads(1)
+ .build()) {
+
+ var executionOrder = new AtomicInteger(0);
+ var startSignal = new CompletableFuture();
+
+ System.out.println("Submitting tasks...");
+ List> taskFutures = Arrays.stream(TaskType.values())
+ .map(taskType -> {
+ System.out.println("Submitting task: " + taskType);
+ return createTask(taskType, executionOrder, startSignal, pool);
+ })
+ .toList();
+
+ System.out.println("Starting all tasks");
+ startSignal.complete(null);
+
+ List results = CompletableFuture.allOf(taskFutures.toArray(CompletableFuture[]::new))
+ .thenApply(v -> taskFutures.stream()
+ .map(CompletableFuture::join)
+ .toList())
+ .orTimeout(30, TimeUnit.SECONDS)
+ .exceptionally(ex -> {
+ fail("Task execution failed or timed out: " + ex.getMessage());
+ return List.of();
+ })
+ .join();
+
+ System.out.println("All tasks completed");
+ verifyExecutionOrder(results);
+ verifyLightWeightTaskExecution(results);
+ printExecutionStatistics(results);
+ }
+ }
+
+ private CompletableFuture createTask(TaskType taskType, AtomicInteger executionOrder, CompletableFuture startSignal, DynamicPriorityThreadPool pool) {
+ return startSignal.thenCompose(ignored -> {
+ PriorityTask task = PriorityTask.createCallableTask(() -> {
+ var start = Instant.now();
+ try {
+ // 使用固定的睡眠时间,以避免执行时间影响优先级顺序
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ var end = Instant.now();
+ var order = executionOrder.incrementAndGet();
+ System.out.printf("Task %s completed. Order: %d%n", taskType, order);
+ return new TaskExecution(taskType, start, end, order);
+ }, taskType);
+
+ return CompletableFuture.supplyAsync(() -> {
+ try {
+ return pool.submit((Callable) task).get();
+ } catch (Exception e) {
+ throw new CompletionException(e);
+ }
+ });
+ });
+ }
+
+ private void verifyExecutionOrder(List results) {
+ for (int i = 0; i < results.size() - 1; i++) {
+ var current = results.get(i);
+ var next = results.get(i + 1);
+ assertTrue(current.type().getPriority() <= next.type().getPriority(),
+ () -> String.format("Tasks should be executed in priority order. %s (priority %d) " +
+ "should be executed before or at the same time as %s (priority %d)",
+ current.type(), current.type().getPriority(),
+ next.type(), next.type().getPriority()));
+ }
+
+ var firstTask = results.get(0);
+ assertTrue(firstTask.type().isLightWeight(),
+ () -> "The first executed task should be a light-weight task. Actual: " + firstTask.type());
+ }
+
+ private void verifyLightWeightTaskExecution(List results) {
+ var lightWeightTasks = results.stream()
+ .filter(task -> task.type().isLightWeight())
+ .toList();
+
+ assertFalse(lightWeightTasks.isEmpty(), "There should be at least one light-weight task");
+
+ var firstTaskStartTime = lightWeightTasks.get(0).startTime();
+ for (var task : lightWeightTasks) {
+ var executionDelay = Duration.between(firstTaskStartTime, task.startTime());
+ assertTrue(executionDelay.toMillis() < 50,
+ () -> String.format("Light-weight task %s should start within 50ms of the first task. " +
+ "Actual delay: %d ms", task.type(), executionDelay.toMillis()));
+ }
+ }
+
+ private void printExecutionStatistics(List results) {
+ System.out.println("\nTask Execution Statistics:");
+ results.forEach(task -> System.out.printf("%s: Order=%d, Duration=%d ms%n",
+ task.type(), task.executionOrder(),
+ Duration.between(task.startTime(), task.endTime()).toMillis()));
+ }
+}
diff --git a/quick-landing/pom.xml b/quick-landing/pom.xml
index 7dfb4caf567730eef5152f37aa67153ca011b91c..ea18cf2a456940b21e533d1cf2e8e81f6cc1bd6f 100644
--- a/quick-landing/pom.xml
+++ b/quick-landing/pom.xml
@@ -15,6 +15,7 @@
https://gitee.com/MagicJson/learning-training.git
dynamic-rest-caller
+ dynamic-priority-executors
diff --git a/uml-adapter-architecture/LobeChat.yml b/uml-adapter-architecture/LobeChat.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d9750ebc2bffa48c899ff3cc7c1bda49ce495f97
--- /dev/null
+++ b/uml-adapter-architecture/LobeChat.yml
@@ -0,0 +1,13 @@
+version: '3.8'
+
+services:
+ lobe-chat:
+ image: lobehub/lobe-chat
+ container_name: lobe-chat
+ restart: always
+ ports:
+ - '3210:3210'
+ environment:
+ OPENAI_API_KEY: sess-Vzqgt1wlhovMf50SEjci3XAvCeMTqZAJXU4Yl0nE
+ OPENAI_PROXY_URL: https://api-proxy.com/v1
+ ACCESS_CODE: lobe66
\ No newline at end of file