去掉Service.stop 增加 @Command 功能
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
28
src/org/redkale/util/Command.java
Normal file
28
src/org/redkale/util/Command.java
Normal 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 {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user