去掉Service.stop 增加 @Command 功能

This commit is contained in:
Redkale
2020-06-18 15:35:40 +08:00
parent be0fdd9045
commit b8719d7f76
5 changed files with 121 additions and 5 deletions

View File

@@ -764,7 +764,8 @@ public final class Application {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
if ("SHUTDOWN".equalsIgnoreCase(new String(bytes))) {
final String cmd = new String(bytes);
if ("SHUTDOWN".equalsIgnoreCase(cmd)) {
try {
long s = System.currentTimeMillis();
logger.info(application.getClass().getSimpleName() + " shutdowning");
@@ -784,7 +785,7 @@ public final class Application {
buffer.flip();
channel.send(buffer, address);
}
} else if ("APIDOC".equalsIgnoreCase(new String(bytes))) {
} else if ("APIDOC".equalsIgnoreCase(cmd)) {
try {
new ApiDocsService(application).run();
buffer.clear();
@@ -797,6 +798,16 @@ public final class Application {
buffer.flip();
channel.send(buffer, address);
}
} else {
long s = System.currentTimeMillis();
logger.info(application.getClass().getSimpleName() + " command " + cmd);
application.command(cmd);
buffer.clear();
buffer.put("COMMAND OK".getBytes());
buffer.flip();
channel.send(buffer, address);
long e = System.currentTimeMillis() - s;
logger.info(application.getClass().getSimpleName() + " command in " + e + " ms");
}
}
} catch (Exception e) {
@@ -1095,6 +1106,17 @@ public final class Application {
return null;
}
public void command(String cmd) {
List<NodeServer> localServers = new ArrayList<>(servers); //顺序sncps, others, watchs
localServers.stream().forEach((server) -> {
try {
server.command(cmd);
} catch (Exception t) {
logger.log(Level.WARNING, " command server(" + server.getSocketAddress() + ") error", t);
}
});
}
public void shutdown() throws Exception {
for (ApplicationListener listener : this.listeners) {
try {

View File

@@ -461,7 +461,7 @@ public abstract class NodeServer {
final ResourceFactory.ResourceLoader resourceLoader = (ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) -> {
try {
if (SncpClient.parseMethod(serviceImplClass).isEmpty() && serviceImplClass.getAnnotation(Priority.class) == null) { //class没有可用的方法且没有标记启动优先级的 通常为BaseService
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")){
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) {
logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method");
}
return;
@@ -535,8 +535,8 @@ public abstract class NodeServer {
}
if (isSNCP() && !sncpRemoteAgents.isEmpty()) {
sncpRemoteAgents.values().forEach(agent -> {
// agent.putSncpResp((NodeSncpServer) this);
// agent.startSncpRespConsumer();
// agent.putSncpResp((NodeSncpServer) this);
// agent.startSncpRespConsumer();
});
}
//----------------- init -----------------
@@ -773,6 +773,42 @@ public abstract class NodeServer {
server.shutdown();
}
public void command(String cmd) throws IOException {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final boolean finest = logger.isLoggable(Level.FINEST);
localServices.forEach(y -> {
Set<Method> methods = new HashSet<>();
Class loop = y.getClass();
//do { public方法不用递归
for (Method m : loop.getMethods()) {
Command c = m.getAnnotation(Command.class);
if (c == null) continue;
if (Modifier.isStatic(m.getModifiers())) continue;
if (m.getReturnType() != void.class) continue;
if (m.getParameterCount() != 1) continue;
if (m.getParameterTypes()[0] != String.class) continue;
methods.add(m);
}
//} while ((loop = loop.getSuperclass()) != Object.class);
if (methods.isEmpty()) return;
long s = System.currentTimeMillis();
Method one = null;
try {
for (Method method : methods) {
one = method;
method.invoke(y, cmd);
}
} catch (Exception ex) {
logger.log(Level.SEVERE, one + " run error, cmd = " + cmd, ex);
}
long e = System.currentTimeMillis() - s;
if (e > 10 && sb != null) {
sb.append(Sncp.toSimpleString(y, maxNameLength, maxClassNameLength)).append(" command (").append(cmd).append(") ").append(e).append("ms").append(LINE_SEPARATOR);
}
});
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
public <T extends Server> T getServer() {
return (T) server;
}

View File

@@ -0,0 +1,28 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.util;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 接收命令的标记, 只能标记在本地模式下Service里参数为String且返回类型为void的public方法上
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
@Inherited
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface Command {
}