diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/Agent.java b/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/Agent.java index a3a6b6e1..4c7bed08 100644 --- a/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/Agent.java +++ b/Partner-Framework/src/main/java/work/slhaf/partner/framework/agent/Agent.java @@ -1,5 +1,6 @@ package work.slhaf.partner.framework.agent; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import work.slhaf.partner.framework.agent.config.ConfigCenter; import work.slhaf.partner.framework.agent.exception.AgentLaunchFailedException; @@ -21,35 +22,44 @@ import java.util.Set; @Slf4j public final class Agent { - public static AgentStep newAgent(Class clazz) { - if (clazz == null) { - throw new AgentLaunchFailedException("Agent class 和 interaction flow context 不能为 null"); - } + public static AgentApp newAgent(@NonNull Class clazz) { return new AgentApp(clazz); } - public interface AgentStep { - AgentStep addGatewayRegistration(AgentGatewayRegistration... registrations); - - void launch(); - } - - public static class AgentApp implements AgentStep { + public static class AgentApp { private final Class applicationClass; private final Set gatewayRegistrations = new LinkedHashSet<>(); + private final Set preShutdownHooks = new LinkedHashSet<>(); + private final Set postShutdownHooks = new LinkedHashSet<>(); private AgentApp(Class clazz) { this.applicationClass = clazz; } - @Override - public AgentStep addGatewayRegistration(AgentGatewayRegistration... registrations) { + public AgentApp addGatewayRegistration(AgentGatewayRegistration... registrations) { this.gatewayRegistrations.addAll(Set.of(registrations)); return this; } - @Override + public AgentApp addPreShutdownHook(String name, Runnable action) { + return addPreShutdownHook(name, 0, action); + } + + public AgentApp addPreShutdownHook(String name, int order, Runnable action) { + this.preShutdownHooks.add(new LifecycleHook(name, order, action)); + return this; + } + + public AgentApp addPostShutdownHook(String name, Runnable action) { + return addPostShutdownHook(name, 0, action); + } + + public AgentApp addPostShutdownHook(String name, int order, Runnable action) { + this.postShutdownHooks.add(new LifecycleHook(name, order, action)); + return this; + } + public void launch() { try { // Keep startup order explicit so registries are ready before component scanning. @@ -59,21 +69,7 @@ public final class Agent { for (AgentGatewayRegistration registration : gatewayRegistrations) { registration.register(); } - AgentContext.INSTANCE.addPreShutdownHook( - "agent-gateway-registry-close", - 0, - AgentGatewayRegistry.INSTANCE::close - ); - AgentContext.INSTANCE.addPostShutdownHook( - "state-center-save", - 0, - StateCenter.INSTANCE::save - ); - AgentContext.INSTANCE.addPostShutdownHook( - "config-center-close", - 100, - ConfigCenter.INSTANCE::close - ); + registerShutdownHooks(); Path externalModuleDir = ConfigCenter.INSTANCE.getPaths().getResourcesDir().resolve("module"); AgentRegisterFactory.addScanDir(externalModuleDir.toString()); AgentRegisterFactory.launch(applicationClass.getPackageName()); @@ -83,6 +79,33 @@ public final class Agent { throw new AgentLaunchFailedException("Agent 启动失败", e); } } + + private void registerShutdownHooks() { + AgentContext.INSTANCE.addPreShutdownHook( + "agent-gateway-registry-close", + 0, + AgentGatewayRegistry.INSTANCE::close + ); + preShutdownHooks.forEach(hook -> + AgentContext.INSTANCE.addPreShutdownHook(hook.name(), hook.order(), hook.action()) + ); + AgentContext.INSTANCE.addPostShutdownHook( + "state-center-save", + 0, + StateCenter.INSTANCE::save + ); + AgentContext.INSTANCE.addPostShutdownHook( + "config-center-close", + 100, + ConfigCenter.INSTANCE::close + ); + postShutdownHooks.forEach(hook -> + AgentContext.INSTANCE.addPostShutdownHook(hook.name(), hook.order(), hook.action()) + ); + } + } + + private record LifecycleHook(String name, int order, Runnable action) { } }