实现@NonBlocking
This commit is contained in:
@@ -6,13 +6,12 @@ package org.redkale.annotation;
|
|||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 非阻塞模式标记, 标记在Service类和方法、HttpServlet类上 <br>
|
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
|
||||||
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
|
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
|
||||||
* 1、返回类型是CompletableFuture <br>
|
* 1、返回类型是CompletionStage <br>
|
||||||
* 2、返回类型是void且参数存在CompletionHandler类型 <br>
|
* 2、返回类型是void且参数存在CompletionHandler类型 <br>
|
||||||
* 阻塞模式的方法会在work线程池中运行, 非阻塞在IO线程中运行。
|
* 阻塞模式的方法会在work线程池中运行, 非阻塞在IO线程中运行。
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
*
|
*
|
||||||
@@ -22,7 +21,7 @@ import java.lang.annotation.*;
|
|||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface NonBlocking {
|
public @interface NonBlocking { //不可使用@Inherited,防止被继承, 见HttpServlet.preExecute/authenticate/execute
|
||||||
|
|
||||||
boolean value() default true;
|
boolean value() default true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.redkale.annotation.*;
|
import org.redkale.annotation.*;
|
||||||
|
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
|
||||||
import org.redkale.boot.ClassFilter.FilterEntry;
|
import org.redkale.boot.ClassFilter.FilterEntry;
|
||||||
import org.redkale.cluster.ClusterAgent;
|
import org.redkale.cluster.ClusterAgent;
|
||||||
import org.redkale.mq.MessageAgent;
|
import org.redkale.mq.MessageAgent;
|
||||||
@@ -24,7 +25,6 @@ import org.redkale.service.Service;
|
|||||||
import org.redkale.util.AnyValue.DefaultAnyValue;
|
import org.redkale.util.AnyValue.DefaultAnyValue;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
import org.redkale.watch.*;
|
import org.redkale.watch.*;
|
||||||
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP Server节点的配置Server
|
* HTTP Server节点的配置Server
|
||||||
|
|||||||
@@ -111,14 +111,8 @@ public class Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void executeDispatch(Request request, Response response) {
|
protected void executeDispatch(Request request, Response response) {
|
||||||
if (workHashExecutor != null) {
|
|
||||||
workHashExecutor.execute(request.getHashid(), () -> dispatcher.dispatch(request, response));
|
|
||||||
} else if (workExecutor != null) {
|
|
||||||
workExecutor.execute(() -> dispatcher.dispatch(request, response));
|
|
||||||
} else {
|
|
||||||
dispatcher.dispatch(request, response);
|
dispatcher.dispatch(request, response);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(Servlet servlet, Request request, Response response) {
|
public void execute(Servlet servlet, Request request, Response response) {
|
||||||
if (workHashExecutor != null) {
|
if (workHashExecutor != null) {
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ public abstract class DispatcherServlet<K extends Serializable, C extends Contex
|
|||||||
|
|
||||||
protected Filter<C, R, P> headFilter;
|
protected Filter<C, R, P> headFilter;
|
||||||
|
|
||||||
|
protected DispatcherServlet() {
|
||||||
|
this._nonBlocking = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected void incrExecuteCounter() {
|
protected void incrExecuteCounter() {
|
||||||
executeCounter.increment();
|
executeCounter.increment();
|
||||||
}
|
}
|
||||||
@@ -290,8 +294,8 @@ public abstract class DispatcherServlet<K extends Serializable, C extends Contex
|
|||||||
response.inNonBlocking = true;
|
response.inNonBlocking = true;
|
||||||
response.nextEvent();
|
response.nextEvent();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
response.context.logger.log(Level.WARNING, "prepare servlet abort, force to close channel ", t);
|
response.context.logger.log(Level.WARNING, "Dispatch servlet occur exception", t);
|
||||||
response.error(t);
|
response.finishError(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
package org.redkale.net;
|
package org.redkale.net;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.redkale.annotation.Priority;
|
import org.redkale.annotation.*;
|
||||||
import org.redkale.util.AnyValue;
|
import org.redkale.util.AnyValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 协议拦截器类, 类似JavaEE中的javax.servlet.Filter <br>
|
* 协议拦截器类, 类似JavaEE中的javax.servlet.Filter <br>
|
||||||
* javax.servlet.Filter方法doFilter是同步操作,此Filter.doFilter则是异步操作,方法return前需要调用Response.nextEvent()方可执行下一个Filter <br>
|
* javax.servlet.Filter方法doFilter是同步操作,此Filter.doFilter则是异步操作,方法return前需要调用Response.nextEvent()方可执行下一个Filter <br>
|
||||||
* 通过给Filter标记注解@Priority来确定执行的顺序, Priority.value值越大越先执行
|
* 通过给Filter标记注解@Priority来确定执行的顺序, Priority.value值越大越先执行 <br>
|
||||||
|
* 如果doFilter方法是非阻塞的,需要在Filter类上标记@NonBlocking
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
@@ -26,15 +27,20 @@ public abstract class Filter<C extends Context, R extends Request<C>, P extends
|
|||||||
|
|
||||||
AnyValue _conf; //当前Filter的配置
|
AnyValue _conf; //当前Filter的配置
|
||||||
|
|
||||||
|
final boolean _nonBlocking; //当前Filter.doFilter方法是否为阻塞模式
|
||||||
|
|
||||||
Filter<C, R, P> _next; //下一个Filter
|
Filter<C, R, P> _next; //下一个Filter
|
||||||
|
|
||||||
|
protected Filter() {
|
||||||
|
NonBlocking a = getClass().getAnnotation(NonBlocking.class);
|
||||||
|
this._nonBlocking = a != null && a.value();
|
||||||
|
}
|
||||||
|
|
||||||
public void init(C context, AnyValue config) {
|
public void init(C context, AnyValue config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void doFilter(R request, P response) throws IOException;
|
public abstract void doFilter(R request, P response) throws IOException;
|
||||||
|
|
||||||
public abstract boolean isNonBlocking();
|
|
||||||
|
|
||||||
public void destroy(C context, AnyValue config) {
|
public void destroy(C context, AnyValue config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,4 +53,8 @@ public abstract class Filter<C extends Context, R extends Request<C>, P extends
|
|||||||
Priority p2 = o.getClass().getAnnotation(Priority.class);
|
Priority p2 = o.getClass().getAnnotation(Priority.class);
|
||||||
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
|
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isNonBlocking() {
|
||||||
|
return _nonBlocking;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.redkale.net;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.CompletionHandler;
|
import java.nio.channels.CompletionHandler;
|
||||||
|
import java.util.concurrent.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
@@ -31,6 +32,8 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
|
|
||||||
protected Consumer<Response> responseConsumer; //虚拟构建的Response可能不存在responseConsumer
|
protected Consumer<Response> responseConsumer; //虚拟构建的Response可能不存在responseConsumer
|
||||||
|
|
||||||
|
protected final ExecutorService workExecutor;
|
||||||
|
|
||||||
protected final R request;
|
protected final R request;
|
||||||
|
|
||||||
protected final WorkThread thread;
|
protected final WorkThread thread;
|
||||||
@@ -118,6 +121,7 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
this.request = request;
|
this.request = request;
|
||||||
this.thread = WorkThread.currWorkThread();
|
this.thread = WorkThread.currWorkThread();
|
||||||
this.writeBuffer = context != null ? ByteBuffer.allocateDirect(context.getBufferCapacity()) : null;
|
this.writeBuffer = context != null ? ByteBuffer.allocateDirect(context.getBufferCapacity()) : null;
|
||||||
|
this.workExecutor = context == null || context.workExecutor == null ? ForkJoinPool.commonPool() : context.workExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AsyncConnection removeChannel() {
|
protected AsyncConnection removeChannel() {
|
||||||
@@ -154,6 +158,14 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ExecutorService getWorkExecutor() {
|
||||||
|
return workExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateNonBlocking(boolean nonBlocking) {
|
||||||
|
this.inNonBlocking = nonBlocking;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean inNonBlocking() {
|
protected boolean inNonBlocking() {
|
||||||
return inNonBlocking;
|
return inNonBlocking;
|
||||||
}
|
}
|
||||||
@@ -181,13 +193,45 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
if (this.filter != null) {
|
if (this.filter != null) {
|
||||||
Filter runner = this.filter;
|
Filter runner = this.filter;
|
||||||
this.filter = this.filter._next;
|
this.filter = this.filter._next;
|
||||||
|
if (inNonBlocking) {
|
||||||
|
if (runner.isNonBlocking()) {
|
||||||
runner.doFilter(request, this);
|
runner.doFilter(request, this);
|
||||||
|
} else {
|
||||||
|
inNonBlocking = false;
|
||||||
|
workExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
runner.doFilter(request, Response.this);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
context.getLogger().log(Level.WARNING, "Filter occur exception. request = " + request, t);
|
||||||
|
finishError(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runner.doFilter(request, this);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.servlet != null) {
|
if (this.servlet != null) {
|
||||||
Servlet s = this.servlet;
|
Servlet s = this.servlet;
|
||||||
this.servlet = null;
|
this.servlet = null;
|
||||||
|
if (inNonBlocking) {
|
||||||
|
if (s.isNonBlocking()) {
|
||||||
s.execute(request, this);
|
s.execute(request, this);
|
||||||
|
} else {
|
||||||
|
inNonBlocking = false;
|
||||||
|
workExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
s.execute(request, Response.this);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
context.getLogger().log(Level.WARNING, "Servlet occur exception. request = " + request, t);
|
||||||
|
finishError(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.execute(request, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +256,12 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
this.completeInIOThread(false);
|
this.completeInIOThread(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//被重载后kill不一定为true
|
||||||
|
protected void finishError(Throwable t) {
|
||||||
|
error(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//kill=true
|
||||||
protected void error(Throwable t) {
|
protected void error(Throwable t) {
|
||||||
completeInIOThread(true);
|
completeInIOThread(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.net;
|
package org.redkale.net;
|
||||||
|
|
||||||
import org.redkale.util.AnyValue;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import org.redkale.util.AnyValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 协议请求处理类
|
* 协议请求处理类
|
||||||
@@ -23,6 +23,8 @@ public abstract class Servlet<C extends Context, R extends Request<C>, P extends
|
|||||||
|
|
||||||
AnyValue _conf; //当前Servlet的配置
|
AnyValue _conf; //当前Servlet的配置
|
||||||
|
|
||||||
|
protected boolean _nonBlocking; //当前Servlet.execute方法是否为非阻塞模式
|
||||||
|
|
||||||
//Server执行start时运行此方法
|
//Server执行start时运行此方法
|
||||||
public void init(C context, AnyValue config) {
|
public void init(C context, AnyValue config) {
|
||||||
}
|
}
|
||||||
@@ -33,4 +35,7 @@ public abstract class Servlet<C extends Context, R extends Request<C>, P extends
|
|||||||
public void destroy(C context, AnyValue config) {
|
public void destroy(C context, AnyValue config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isNonBlocking() {
|
||||||
|
return _nonBlocking;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ public class HttpDispatcherServlet extends DispatcherServlet<String, HttpContext
|
|||||||
|
|
||||||
private HttpServlet lastRunServlet;
|
private HttpServlet lastRunServlet;
|
||||||
|
|
||||||
|
protected HttpDispatcherServlet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
private List<HttpServlet> removeHttpServlet(final Predicate<MappingEntry> predicateEntry, final Predicate<Map.Entry<String, WebSocketServlet>> predicateFilter) {
|
private List<HttpServlet> removeHttpServlet(final Predicate<MappingEntry> predicateEntry, final Predicate<Map.Entry<String, WebSocketServlet>> predicateFilter) {
|
||||||
List<HttpServlet> servlets = new ArrayList<>();
|
List<HttpServlet> servlets = new ArrayList<>();
|
||||||
allMapLock.lock();
|
allMapLock.lock();
|
||||||
@@ -354,8 +358,8 @@ public class HttpDispatcherServlet extends DispatcherServlet<String, HttpContext
|
|||||||
}
|
}
|
||||||
servlet.execute(request, response);
|
servlet.execute(request, response);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
request.getContext().getLogger().log(Level.WARNING, "Servlet occur, force to close channel. request = " + request, e);
|
request.getContext().getLogger().log(Level.WARNING, "Dispatch servlet occur exception. request = " + request, e);
|
||||||
response.finish(500, null);
|
response.finishError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,6 +236,21 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
return super.recycle();
|
return super.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExecutorService getWorkExecutor() {
|
||||||
|
return super.getWorkExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateNonBlocking(boolean nonBlocking) {
|
||||||
|
super.updateNonBlocking(nonBlocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean inNonBlocking() {
|
||||||
|
return super.inNonBlocking();
|
||||||
|
}
|
||||||
|
|
||||||
// protected Supplier<ByteBuffer> getBodyBufferSupplier() {
|
// protected Supplier<ByteBuffer> getBodyBufferSupplier() {
|
||||||
// return bodyBufferSupplier;
|
// return bodyBufferSupplier;
|
||||||
// }
|
// }
|
||||||
@@ -308,10 +323,15 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
finish(v);
|
finish(v);
|
||||||
}, (t, a) -> {
|
}, (t, a) -> {
|
||||||
context.getLogger().log(Level.WARNING, "Servlet occur, force to close channel. request = " + request + ", result is CompletionHandler", (Throwable) t);
|
context.getLogger().log(Level.WARNING, "Servlet occur, force to close channel. request = " + request + ", result is CompletionHandler", (Throwable) t);
|
||||||
finish(500, null);
|
finishError(t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finishError(Throwable t) {
|
||||||
|
finish(500, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建CompletionHandler子类的实例 <br>
|
* 创建CompletionHandler子类的实例 <br>
|
||||||
*
|
*
|
||||||
@@ -620,7 +640,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
public void finishFuture(final Convert convert, Type valueType, CompletionStage future) {
|
public void finishFuture(final Convert convert, Type valueType, CompletionStage future) {
|
||||||
future.whenComplete((v, e) -> {
|
future.whenComplete((v, e) -> {
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
context.getLogger().log(Level.WARNING, "Servlet occur, force to close channel. request = " + request + ", result is CompletionStage", (Throwable) e);
|
context.getLogger().log(Level.WARNING, "Servlet occur exception. request = " + request + ", result is CompletionStage", (Throwable) e);
|
||||||
if (e instanceof TimeoutException) {
|
if (e instanceof TimeoutException) {
|
||||||
finish504();
|
finish504();
|
||||||
} else {
|
} else {
|
||||||
@@ -652,7 +672,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
public void finishJsonFuture(final Convert convert, Type valueType, CompletionStage future) {
|
public void finishJsonFuture(final Convert convert, Type valueType, CompletionStage future) {
|
||||||
future.whenComplete((v, e) -> {
|
future.whenComplete((v, e) -> {
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
context.getLogger().log(Level.WARNING, "Servlet occur, force to close channel. request = " + request + ", result is CompletionStage", (Throwable) e);
|
context.getLogger().log(Level.WARNING, "Servlet occur exception. request = " + request + ", result is CompletionStage", (Throwable) e);
|
||||||
if (e instanceof TimeoutException) {
|
if (e instanceof TimeoutException) {
|
||||||
finish504();
|
finish504();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ package org.redkale.net.http;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.redkale.annotation.NonBlocking;
|
||||||
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
||||||
import org.redkale.asm.*;
|
import org.redkale.asm.*;
|
||||||
import static org.redkale.asm.Opcodes.*;
|
import static org.redkale.asm.Opcodes.*;
|
||||||
@@ -48,6 +50,10 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
|
|
||||||
//这里不能直接使用HttpServlet,会造成死循环初始化HttpServlet
|
//这里不能直接使用HttpServlet,会造成死循环初始化HttpServlet
|
||||||
private final Servlet<HttpContext, HttpRequest, HttpResponse> authSuccessServlet = new Servlet<HttpContext, HttpRequest, HttpResponse>() {
|
private final Servlet<HttpContext, HttpRequest, HttpResponse> authSuccessServlet = new Servlet<HttpContext, HttpRequest, HttpResponse>() {
|
||||||
|
{
|
||||||
|
this._nonBlocking = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(HttpRequest request, HttpResponse response) throws IOException {
|
public void execute(HttpRequest request, HttpResponse response) throws IOException {
|
||||||
ActionEntry entry = request.actionEntry;
|
ActionEntry entry = request.actionEntry;
|
||||||
@@ -72,12 +78,32 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
}
|
}
|
||||||
response.setCacheHandler(entry.cacheHandler);
|
response.setCacheHandler(entry.cacheHandler);
|
||||||
}
|
}
|
||||||
|
if (response.inNonBlocking()) {
|
||||||
|
if (entry.nonBlocking) {
|
||||||
entry.servlet.execute(request, response);
|
entry.servlet.execute(request, response);
|
||||||
|
} else {
|
||||||
|
response.updateNonBlocking(false);
|
||||||
|
response.getWorkExecutor().execute(() -> {
|
||||||
|
try {
|
||||||
|
entry.servlet.execute(request, response);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
response.getContext().getLogger().log(Level.WARNING, "Servlet occur exception. request = " + request, t);
|
||||||
|
response.finishError(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry.servlet.execute(request, response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//preExecute运行完后执行的Servlet
|
//preExecute运行完后执行的Servlet
|
||||||
private final Servlet<HttpContext, HttpRequest, HttpResponse> preSuccessServlet = new Servlet<HttpContext, HttpRequest, HttpResponse>() {
|
private final Servlet<HttpContext, HttpRequest, HttpResponse> preSuccessServlet = new Servlet<HttpContext, HttpRequest, HttpResponse>() {
|
||||||
|
{
|
||||||
|
this._nonBlocking = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(HttpRequest request, HttpResponse response) throws IOException {
|
public void execute(HttpRequest request, HttpResponse response) throws IOException {
|
||||||
if (request.actionEntry != null) {
|
if (request.actionEntry != null) {
|
||||||
@@ -134,7 +160,10 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
if (ws != null && !ws.repair()) {
|
if (ws != null && !ws.repair()) {
|
||||||
path = "";
|
path = "";
|
||||||
}
|
}
|
||||||
HashMap<String, ActionEntry> map = this._actionmap != null ? this._actionmap : loadActionEntry();
|
//设置整个HttpServlet是否非阻塞式
|
||||||
|
this._nonBlocking = isNonBlocking(getClass());
|
||||||
|
//RestServlet会填充_actionmap
|
||||||
|
HashMap<String, ActionEntry> map = this._actionmap != null ? this._actionmap : loadActionEntry(this._nonBlocking);
|
||||||
this.mappings = new Map.Entry[map.size()];
|
this.mappings = new Map.Entry[map.size()];
|
||||||
int i = -1;
|
int i = -1;
|
||||||
for (Map.Entry<String, ActionEntry> en : map.entrySet()) {
|
for (Map.Entry<String, ActionEntry> en : map.entrySet()) {
|
||||||
@@ -201,6 +230,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
*
|
*
|
||||||
* @throws IOException IOException
|
* @throws IOException IOException
|
||||||
*/
|
*/
|
||||||
|
@NonBlocking
|
||||||
protected void preExecute(HttpRequest request, HttpResponse response) throws IOException {
|
protected void preExecute(HttpRequest request, HttpResponse response) throws IOException {
|
||||||
response.nextEvent();
|
response.nextEvent();
|
||||||
}
|
}
|
||||||
@@ -227,17 +257,74 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
*
|
*
|
||||||
* @throws IOException IOException
|
* @throws IOException IOException
|
||||||
*/
|
*/
|
||||||
|
@NonBlocking
|
||||||
protected void authenticate(HttpRequest request, HttpResponse response) throws IOException {
|
protected void authenticate(HttpRequest request, HttpResponse response) throws IOException {
|
||||||
response.nextEvent();
|
response.nextEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonBlocking
|
||||||
public void execute(HttpRequest request, HttpResponse response) throws IOException {
|
public void execute(HttpRequest request, HttpResponse response) throws IOException {
|
||||||
response.thenEvent(preSuccessServlet);
|
response.thenEvent(preSuccessServlet);
|
||||||
preExecute(request, response);
|
preExecute(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<String, ActionEntry> loadActionEntry() {
|
static Boolean isNonBlocking(Class<?> servletClass) {
|
||||||
|
Class clz = servletClass;
|
||||||
|
Boolean preNonBlocking = null;
|
||||||
|
Boolean authNonBlocking = null;
|
||||||
|
Boolean exeNonBlocking = null;
|
||||||
|
do {
|
||||||
|
if (java.lang.reflect.Modifier.isAbstract(clz.getModifiers())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RedkaleClassLoader.putReflectionDeclaredMethods(clz.getName());
|
||||||
|
for (final Method method : clz.getDeclaredMethods()) {
|
||||||
|
String methodName = method.getName();
|
||||||
|
//-----------------------------------------------
|
||||||
|
Class[] paramTypes = method.getParameterTypes();
|
||||||
|
if (paramTypes.length != 2 || paramTypes[0] != HttpRequest.class || paramTypes[1] != HttpResponse.class) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------
|
||||||
|
Class[] exps = method.getExceptionTypes();
|
||||||
|
if (exps.length > 0 && (exps.length != 1 || exps[0] != IOException.class)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------
|
||||||
|
if ("preExecute".equals(methodName)) {
|
||||||
|
if (preNonBlocking == null) {
|
||||||
|
NonBlocking non = method.getAnnotation(NonBlocking.class);
|
||||||
|
preNonBlocking = non != null && non.value();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ("authenticate".equals(methodName)) {
|
||||||
|
if (authNonBlocking == null) {
|
||||||
|
NonBlocking non = method.getAnnotation(NonBlocking.class);
|
||||||
|
authNonBlocking = non != null && non.value();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ("execute".equals(methodName)) {
|
||||||
|
if (exeNonBlocking == null) {
|
||||||
|
NonBlocking non = method.getAnnotation(NonBlocking.class);
|
||||||
|
exeNonBlocking = non != null && non.value();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ((clz = clz.getSuperclass()) != HttpServlet.class);
|
||||||
|
//设置整个HttpServlet是否非阻塞式
|
||||||
|
NonBlocking non = servletClass.getAnnotation(NonBlocking.class);
|
||||||
|
if (non == null) {
|
||||||
|
return (preNonBlocking != null && preNonBlocking) && (authNonBlocking != null && authNonBlocking) && (exeNonBlocking != null && exeNonBlocking);
|
||||||
|
} else {
|
||||||
|
return non.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String, ActionEntry> loadActionEntry(boolean typeNonBlocking) {
|
||||||
WebServlet module = this.getClass().getAnnotation(WebServlet.class);
|
WebServlet module = this.getClass().getAnnotation(WebServlet.class);
|
||||||
final int serviceid = module == null ? 0 : module.moduleid();
|
final int serviceid = module == null ? 0 : module.moduleid();
|
||||||
final HashMap<String, ActionEntry> map = new HashMap<>();
|
final HashMap<String, ActionEntry> map = new HashMap<>();
|
||||||
@@ -248,13 +335,9 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
if (java.lang.reflect.Modifier.isAbstract(clz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isAbstract(clz.getModifiers())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RedkaleClassLoader.putReflectionPublicMethods(clz.getName());
|
RedkaleClassLoader.putReflectionDeclaredMethods(clz.getName());
|
||||||
for (final Method method : clz.getMethods()) {
|
for (final Method method : clz.getDeclaredMethods()) {
|
||||||
//-----------------------------------------------
|
String methodName = method.getName();
|
||||||
String methodname = method.getName();
|
|
||||||
if ("service".equals(methodname) || "preExecute".equals(methodname) || "execute".equals(methodname) || "authenticate".equals(methodname)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
Class[] paramTypes = method.getParameterTypes();
|
Class[] paramTypes = method.getParameterTypes();
|
||||||
if (paramTypes.length != 2 || paramTypes[0] != HttpRequest.class || paramTypes[1] != HttpResponse.class) {
|
if (paramTypes.length != 2 || paramTypes[0] != HttpRequest.class || paramTypes[1] != HttpResponse.class) {
|
||||||
@@ -266,6 +349,14 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
|
if ("preExecute".equals(methodName) || "authenticate".equals(methodName)
|
||||||
|
|| "execute".equals(methodName) || "service".equals(methodName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!Modifier.isPublic(method.getModifiers())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------
|
||||||
|
|
||||||
final HttpMapping mapping = method.getAnnotation(HttpMapping.class);
|
final HttpMapping mapping = method.getAnnotation(HttpMapping.class);
|
||||||
if (mapping == null) {
|
if (mapping == null) {
|
||||||
@@ -285,7 +376,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
throw new HttpException(this.getClass().getSimpleName() + " have two same " + HttpMapping.class.getSimpleName() + "(" + name + ")");
|
throw new HttpException(this.getClass().getSimpleName() + " have two same " + HttpMapping.class.getSimpleName() + "(" + name + ")");
|
||||||
}
|
}
|
||||||
nameset.put(name, clz);
|
nameset.put(name, clz);
|
||||||
map.put(name, new ActionEntry(serviceid, actionid, name, methods, method, createActionServlet(method)));
|
map.put(name, new ActionEntry(serviceid, actionid, name, methods, method, createActionServlet(typeNonBlocking, method)));
|
||||||
}
|
}
|
||||||
} while ((clz = clz.getSuperclass()) != HttpServlet.class);
|
} while ((clz = clz.getSuperclass()) != HttpServlet.class);
|
||||||
return map;
|
return map;
|
||||||
@@ -331,6 +422,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
oneCache = new CacheEntry(response.getStatus(), response.getContentType(), content);
|
oneCache = new CacheEntry(response.getStatus(), response.getContentType(), content);
|
||||||
} : null;
|
} : null;
|
||||||
}
|
}
|
||||||
|
this.nonBlocking = servlet._nonBlocking;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean auth(Method method) {
|
protected static boolean auth(Method method) {
|
||||||
@@ -353,10 +445,6 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
return method.getAnnotations();
|
return method.getAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNeedCheck() {
|
|
||||||
return this.moduleid != 0 || this.actionid != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean checkMethod(final String reqMethod) {
|
boolean checkMethod(final String reqMethod) {
|
||||||
if (methods.length == 0) {
|
if (methods.length == 0) {
|
||||||
return true;
|
return true;
|
||||||
@@ -379,6 +467,8 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
|
|
||||||
final boolean rpconly;
|
final boolean rpconly;
|
||||||
|
|
||||||
|
final boolean nonBlocking;
|
||||||
|
|
||||||
final boolean auth;
|
final boolean auth;
|
||||||
|
|
||||||
final int moduleid;
|
final int moduleid;
|
||||||
@@ -398,7 +488,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
Annotation[] annotations;
|
Annotation[] annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpServlet createActionServlet(final Method method) {
|
private HttpServlet createActionServlet(final boolean typeNonBlocking, final Method method) {
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
final String supDynName = HttpServlet.class.getName().replace('.', '/');
|
final String supDynName = HttpServlet.class.getName().replace('.', '/');
|
||||||
final String interName = this.getClass().getName().replace('.', '/');
|
final String interName = this.getClass().getName().replace('.', '/');
|
||||||
@@ -478,6 +568,8 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
java.lang.reflect.Field field = instance.getClass().getField(factfield);
|
java.lang.reflect.Field field = instance.getClass().getField(factfield);
|
||||||
field.set(instance, this);
|
field.set(instance, this);
|
||||||
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), field);
|
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), field);
|
||||||
|
NonBlocking non = method.getAnnotation(NonBlocking.class);
|
||||||
|
instance._nonBlocking = typeNonBlocking ? (non == null ? typeNonBlocking : non.value()) : false;
|
||||||
return instance;
|
return instance;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new HttpException(ex);
|
throw new HttpException(ex);
|
||||||
@@ -517,6 +609,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
|||||||
if (actionSimpleMappingUrl != null && !Utility.contains(actionSimpleMappingUrl, '*', '{', '[', '(', '|', '^', '$', '+', '?', '\\')) {
|
if (actionSimpleMappingUrl != null && !Utility.contains(actionSimpleMappingUrl, '*', '{', '[', '(', '|', '^', '$', '+', '?', '\\')) {
|
||||||
this._actionSimpleMappingUrl = actionSimpleMappingUrl;
|
this._actionSimpleMappingUrl = actionSimpleMappingUrl;
|
||||||
}
|
}
|
||||||
|
this._nonBlocking = actionEntry.nonBlocking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -984,17 +984,61 @@ public final class Rest {
|
|||||||
if (!HttpServlet.class.isAssignableFrom(baseServletType)) {
|
if (!HttpServlet.class.isAssignableFrom(baseServletType)) {
|
||||||
throw new RestException(baseServletType + " is not HttpServlet Class on createRestServlet");
|
throw new RestException(baseServletType + " is not HttpServlet Class on createRestServlet");
|
||||||
}
|
}
|
||||||
int mod = baseServletType.getModifiers();
|
int parentMod = baseServletType.getModifiers();
|
||||||
if (!java.lang.reflect.Modifier.isPublic(mod)) {
|
if (!java.lang.reflect.Modifier.isPublic(parentMod)) {
|
||||||
throw new RestException(baseServletType + " is not Public Class on createRestServlet");
|
throw new RestException(baseServletType + " is not Public Class on createRestServlet");
|
||||||
}
|
}
|
||||||
if (java.lang.reflect.Modifier.isAbstract(mod)) {
|
Boolean parentNon0 = null;
|
||||||
|
{
|
||||||
|
NonBlocking snon = serviceType.getAnnotation(NonBlocking.class);
|
||||||
|
parentNon0 = snon == null ? null : snon.value();
|
||||||
|
if (HttpServlet.class != baseServletType) {
|
||||||
|
Boolean preNonBlocking = null;
|
||||||
|
Boolean authNonBlocking = null;
|
||||||
|
RedkaleClassLoader.putReflectionDeclaredMethods(baseServletType.getName());
|
||||||
for (Method m : baseServletType.getDeclaredMethods()) {
|
for (Method m : baseServletType.getDeclaredMethods()) {
|
||||||
if (java.lang.reflect.Modifier.isAbstract(m.getModifiers())) { //@since 2.4.0
|
if (java.lang.reflect.Modifier.isAbstract(parentMod) && java.lang.reflect.Modifier.isAbstract(m.getModifiers())) { //@since 2.4.0
|
||||||
throw new RestException(baseServletType + " cannot contains a abstract Method on " + baseServletType);
|
throw new RestException(baseServletType + " cannot contains a abstract Method on " + baseServletType);
|
||||||
}
|
}
|
||||||
|
Class[] paramTypes = m.getParameterTypes();
|
||||||
|
if (paramTypes.length != 2 || paramTypes[0] != HttpRequest.class || paramTypes[1] != HttpResponse.class) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------
|
||||||
|
Class[] exps = m.getExceptionTypes();
|
||||||
|
if (exps.length > 0 && (exps.length != 1 || exps[0] != IOException.class)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------
|
||||||
|
String methodName = m.getName();
|
||||||
|
if ("preExecute".equals(methodName)) {
|
||||||
|
if (preNonBlocking == null) {
|
||||||
|
NonBlocking non = m.getAnnotation(NonBlocking.class);
|
||||||
|
preNonBlocking = non != null && non.value();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ("authenticate".equals(methodName)) {
|
||||||
|
if (authNonBlocking == null) {
|
||||||
|
NonBlocking non = m.getAnnotation(NonBlocking.class);
|
||||||
|
authNonBlocking = non != null && non.value();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (preNonBlocking != null && !preNonBlocking) {
|
||||||
|
parentNon0 = false;
|
||||||
|
} else if (authNonBlocking != null && !authNonBlocking) {
|
||||||
|
parentNon0 = false;
|
||||||
|
} else {
|
||||||
|
NonBlocking bnon = baseServletType.getAnnotation(NonBlocking.class);
|
||||||
|
if (bnon != null && !bnon.value()) {
|
||||||
|
parentNon0 = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final String restInternalName = Type.getInternalName(Rest.class);
|
final String restInternalName = Type.getInternalName(Rest.class);
|
||||||
final String serviceDesc = Type.getDescriptor(serviceType);
|
final String serviceDesc = Type.getDescriptor(serviceType);
|
||||||
final String webServletDesc = Type.getDescriptor(WebServlet.class);
|
final String webServletDesc = Type.getDescriptor(WebServlet.class);
|
||||||
@@ -1002,6 +1046,7 @@ public final class Rest {
|
|||||||
final String reqDesc = Type.getDescriptor(HttpRequest.class);
|
final String reqDesc = Type.getDescriptor(HttpRequest.class);
|
||||||
final String respDesc = Type.getDescriptor(HttpResponse.class);
|
final String respDesc = Type.getDescriptor(HttpResponse.class);
|
||||||
final String convertDesc = Type.getDescriptor(Convert.class);
|
final String convertDesc = Type.getDescriptor(Convert.class);
|
||||||
|
final String nonblockDesc = Type.getDescriptor(NonBlocking.class);
|
||||||
final String typeDesc = Type.getDescriptor(java.lang.reflect.Type.class);
|
final String typeDesc = Type.getDescriptor(java.lang.reflect.Type.class);
|
||||||
final String retDesc = Type.getDescriptor(RetResult.class);
|
final String retDesc = Type.getDescriptor(RetResult.class);
|
||||||
final String httpResultDesc = Type.getDescriptor(HttpResult.class);
|
final String httpResultDesc = Type.getDescriptor(HttpResult.class);
|
||||||
@@ -1041,6 +1086,8 @@ public final class Rest {
|
|||||||
throw new RestException(serviceType + " is ignore Rest Service Class"); //标记为ignore=true不创建Servlet
|
throw new RestException(serviceType + " is ignore Rest Service Class"); //标记为ignore=true不创建Servlet
|
||||||
}
|
}
|
||||||
final boolean serRpcOnly = controller != null && controller.rpconly();
|
final boolean serRpcOnly = controller != null && controller.rpconly();
|
||||||
|
final Boolean parentNonBlocking = parentNon0;
|
||||||
|
|
||||||
ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
|
ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
|
||||||
String stname = serviceType.getSimpleName();
|
String stname = serviceType.getSimpleName();
|
||||||
if (stname.startsWith("Service")) { //类似ServiceWatchService这样的类保留第一个Service字样
|
if (stname.startsWith("Service")) { //类似ServiceWatchService这样的类保留第一个Service字样
|
||||||
@@ -1125,11 +1172,11 @@ public final class Rest {
|
|||||||
paramTypes.add(TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType));
|
paramTypes.add(TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType));
|
||||||
retvalTypes.add(formatRestReturnType(method, serviceType));
|
retvalTypes.add(formatRestReturnType(method, serviceType));
|
||||||
if (mappings.length == 0) { //没有Mapping,设置一个默认值
|
if (mappings.length == 0) { //没有Mapping,设置一个默认值
|
||||||
MappingEntry entry = new MappingEntry(serRpcOnly, methodIdex, null, bigModuleName, method);
|
MappingEntry entry = new MappingEntry(serRpcOnly, methodIdex, parentNonBlocking, null, bigModuleName, method);
|
||||||
entrys.add(entry);
|
entrys.add(entry);
|
||||||
} else {
|
} else {
|
||||||
for (RestMapping mapping : mappings) {
|
for (RestMapping mapping : mappings) {
|
||||||
MappingEntry entry = new MappingEntry(serRpcOnly, methodIdex, mapping, defModuleName, method);
|
MappingEntry entry = new MappingEntry(serRpcOnly, methodIdex, parentNonBlocking, mapping, defModuleName, method);
|
||||||
entrys.add(entry);
|
entrys.add(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1465,8 +1512,8 @@ public final class Rest {
|
|||||||
|
|
||||||
Method restactMethod = newClazz.getDeclaredMethod("_createRestActionEntry");
|
Method restactMethod = newClazz.getDeclaredMethod("_createRestActionEntry");
|
||||||
restactMethod.setAccessible(true);
|
restactMethod.setAccessible(true);
|
||||||
Field tmpentrysfield = HttpServlet.class.getDeclaredField("_actionmap");
|
Field tmpEntrysField = HttpServlet.class.getDeclaredField("_actionmap");
|
||||||
tmpentrysfield.setAccessible(true);
|
tmpEntrysField.setAccessible(true);
|
||||||
HashMap<String, HttpServlet.ActionEntry> innerEntryMap = (HashMap) restactMethod.invoke(obj);
|
HashMap<String, HttpServlet.ActionEntry> innerEntryMap = (HashMap) restactMethod.invoke(obj);
|
||||||
for (Map.Entry<String, HttpServlet.ActionEntry> en : innerEntryMap.entrySet()) {
|
for (Map.Entry<String, HttpServlet.ActionEntry> en : innerEntryMap.entrySet()) {
|
||||||
Method m = mappingUrlToMethod.get(en.getKey());
|
Method m = mappingUrlToMethod.get(en.getKey());
|
||||||
@@ -1474,7 +1521,10 @@ public final class Rest {
|
|||||||
en.getValue().annotations = HttpServlet.ActionEntry.annotations(m);
|
en.getValue().annotations = HttpServlet.ActionEntry.annotations(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmpentrysfield.set(obj, innerEntryMap);
|
tmpEntrysField.set(obj, innerEntryMap);
|
||||||
|
Field nonblockField = Servlet.class.getDeclaredField("_nonBlocking");
|
||||||
|
nonblockField.setAccessible(true);
|
||||||
|
nonblockField.set(obj, parentNonBlocking == null ? true : parentNonBlocking);
|
||||||
return obj;
|
return obj;
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -1587,14 +1637,14 @@ public final class Rest {
|
|||||||
paramTypes.add(TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType));
|
paramTypes.add(TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType));
|
||||||
retvalTypes.add(formatRestReturnType(method, serviceType));
|
retvalTypes.add(formatRestReturnType(method, serviceType));
|
||||||
if (mappings.length == 0) { //没有Mapping,设置一个默认值
|
if (mappings.length == 0) { //没有Mapping,设置一个默认值
|
||||||
MappingEntry entry = new MappingEntry(serRpcOnly, methodidex, null, bigmodulename, method);
|
MappingEntry entry = new MappingEntry(serRpcOnly, methodidex, parentNonBlocking, null, bigmodulename, method);
|
||||||
if (entrys.contains(entry)) {
|
if (entrys.contains(entry)) {
|
||||||
throw new RestException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
|
throw new RestException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
|
||||||
}
|
}
|
||||||
entrys.add(entry);
|
entrys.add(entry);
|
||||||
} else {
|
} else {
|
||||||
for (RestMapping mapping : mappings) {
|
for (RestMapping mapping : mappings) {
|
||||||
MappingEntry entry = new MappingEntry(serRpcOnly, methodidex, mapping, defmodulename, method);
|
MappingEntry entry = new MappingEntry(serRpcOnly, methodidex, parentNonBlocking, mapping, defmodulename, method);
|
||||||
if (entrys.contains(entry)) {
|
if (entrys.contains(entry)) {
|
||||||
throw new RestException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
|
throw new RestException(serviceType.getName() + " on " + method.getName() + " 's mapping(" + entry.name + ") is repeat");
|
||||||
}
|
}
|
||||||
@@ -1667,6 +1717,11 @@ public final class Rest {
|
|||||||
classMap.put("repair", repair);
|
classMap.put("repair", repair);
|
||||||
//classMap.put("comment", comment); //不显示太多信息
|
//classMap.put("comment", comment); //不显示太多信息
|
||||||
}
|
}
|
||||||
|
{ //NonBlocking
|
||||||
|
av0 = cw.visitAnnotation(nonblockDesc, true);
|
||||||
|
av0.visit("value", true);
|
||||||
|
av0.visitEnd();
|
||||||
|
}
|
||||||
{ //内部类
|
{ //内部类
|
||||||
cw.visitInnerClass(actionEntryName, httpServletName, HttpServlet.ActionEntry.class.getSimpleName(), ACC_PROTECTED + ACC_FINAL + ACC_STATIC);
|
cw.visitInnerClass(actionEntryName, httpServletName, HttpServlet.ActionEntry.class.getSimpleName(), ACC_PROTECTED + ACC_FINAL + ACC_STATIC);
|
||||||
|
|
||||||
@@ -2102,8 +2157,7 @@ public final class Rest {
|
|||||||
|
|
||||||
Map<String, Object> mappingMap = new LinkedHashMap<>();
|
Map<String, Object> mappingMap = new LinkedHashMap<>();
|
||||||
java.lang.reflect.Type returnGenericNoFutureType = TypeToken.getGenericType(method.getGenericReturnType(), serviceType);
|
java.lang.reflect.Type returnGenericNoFutureType = TypeToken.getGenericType(method.getGenericReturnType(), serviceType);
|
||||||
{ // 设置 Annotation
|
{ //设置 Annotation HttpMapping
|
||||||
//设置 HttpMapping
|
|
||||||
boolean reqpath = false;
|
boolean reqpath = false;
|
||||||
for (Object[] ps : paramlist) {
|
for (Object[] ps : paramlist) {
|
||||||
if ("#".equals((String) ps[1])) {
|
if ("#".equals((String) ps[1])) {
|
||||||
@@ -2168,7 +2222,12 @@ public final class Rest {
|
|||||||
mappingMap.put("result", returnGenericNoFutureType == returnType ? returnType.getName() : String.valueOf(returnGenericNoFutureType));
|
mappingMap.put("result", returnGenericNoFutureType == returnType ? returnType.getName() : String.valueOf(returnGenericNoFutureType));
|
||||||
entry.mappingurl = url;
|
entry.mappingurl = url;
|
||||||
}
|
}
|
||||||
if (rcs != null && rcs.length > 0) { // 设置 Annotation
|
{ //设置 Annotation NonBlocking
|
||||||
|
av0 = mv.visitAnnotation(nonblockDesc, true);
|
||||||
|
av0.visit("value", entry.nonBlocking);
|
||||||
|
av0.visitEnd();
|
||||||
|
}
|
||||||
|
if (rcs != null && rcs.length > 0) { // 设置 Annotation RestConvert
|
||||||
av0 = mv.visitAnnotation(restConvertsDesc, true);
|
av0 = mv.visitAnnotation(restConvertsDesc, true);
|
||||||
AnnotationVisitor av1 = av0.visitArray("value");
|
AnnotationVisitor av1 = av0.visitArray("value");
|
||||||
//设置 RestConvert
|
//设置 RestConvert
|
||||||
@@ -2197,7 +2256,7 @@ public final class Rest {
|
|||||||
av1.visitEnd();
|
av1.visitEnd();
|
||||||
av0.visitEnd();
|
av0.visitEnd();
|
||||||
}
|
}
|
||||||
if (rcc != null && rcc.length > 0) { // 设置 Annotation
|
if (rcc != null && rcc.length > 0) { // 设置 Annotation RestConvertCoder
|
||||||
av0 = mv.visitAnnotation(restConvertCodersDesc, true);
|
av0 = mv.visitAnnotation(restConvertCodersDesc, true);
|
||||||
AnnotationVisitor av1 = av0.visitArray("value");
|
AnnotationVisitor av1 = av0.visitArray("value");
|
||||||
//设置 RestConvertCoder
|
//设置 RestConvertCoder
|
||||||
@@ -3184,8 +3243,13 @@ public final class Rest {
|
|||||||
cw2.visit(V11, ACC_SUPER, newDynName + "$" + entry.newActionClassName, null, httpServletName, null);
|
cw2.visit(V11, ACC_SUPER, newDynName + "$" + entry.newActionClassName, null, httpServletName, null);
|
||||||
|
|
||||||
cw2.visitInnerClass(newDynName + "$" + entry.newActionClassName, newDynName, entry.newActionClassName, ACC_PRIVATE + ACC_STATIC);
|
cw2.visitInnerClass(newDynName + "$" + entry.newActionClassName, newDynName, entry.newActionClassName, ACC_PRIVATE + ACC_STATIC);
|
||||||
|
{ //设置 Annotation NonBlocking
|
||||||
|
av0 = cw2.visitAnnotation(nonblockDesc, true);
|
||||||
|
av0.visit("value", entry.nonBlocking);
|
||||||
|
av0.visitEnd();
|
||||||
|
}
|
||||||
{
|
{
|
||||||
fv = cw2.visitField(0, "servlet", "L" + newDynName + ";", null, null);
|
fv = cw2.visitField(0, "_parentServlet", "L" + newDynName + ";", null, null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -3194,7 +3258,10 @@ public final class Rest {
|
|||||||
mv.visitMethodInsn(INVOKESPECIAL, httpServletName, "<init>", "()V", false);
|
mv.visitMethodInsn(INVOKESPECIAL, httpServletName, "<init>", "()V", false);
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitVarInsn(ALOAD, 1);
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
mv.visitFieldInsn(PUTFIELD, newDynName + "$" + entry.newActionClassName, "servlet", "L" + newDynName + ";");
|
mv.visitFieldInsn(PUTFIELD, newDynName + "$" + entry.newActionClassName, "_parentServlet", "L" + newDynName + ";");
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitInsn(entry.nonBlocking ? ICONST_1 : ICONST_0);
|
||||||
|
mv.visitFieldInsn(PUTFIELD, newDynName + "$" + entry.newActionClassName, "_nonBlocking", "Z");
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(2, 2);
|
mv.visitMaxs(2, 2);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
@@ -3211,7 +3278,7 @@ public final class Rest {
|
|||||||
{
|
{
|
||||||
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "execute", "(" + reqDesc + respDesc + ")V", null, new String[]{"java/io/IOException"}));
|
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "execute", "(" + reqDesc + respDesc + ")V", null, new String[]{"java/io/IOException"}));
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitFieldInsn(GETFIELD, newDynName + "$" + entry.newActionClassName, "servlet", "L" + newDynName + ";");
|
mv.visitFieldInsn(GETFIELD, newDynName + "$" + entry.newActionClassName, "_parentServlet", "L" + newDynName + ";");
|
||||||
mv.visitVarInsn(ALOAD, 1);
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
mv.visitVarInsn(ALOAD, 2);
|
mv.visitVarInsn(ALOAD, 2);
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, entry.newMethodName, "(" + reqDesc + respDesc + ")V", false);
|
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, entry.newMethodName, "(" + reqDesc + respDesc + ")V", false);
|
||||||
@@ -3416,8 +3483,8 @@ public final class Rest {
|
|||||||
Method restactMethod = newClazz.getDeclaredMethod("_createRestActionEntry");
|
Method restactMethod = newClazz.getDeclaredMethod("_createRestActionEntry");
|
||||||
restactMethod.setAccessible(true);
|
restactMethod.setAccessible(true);
|
||||||
RedkaleClassLoader.putReflectionMethod(newDynName.replace('/', '.'), restactMethod);
|
RedkaleClassLoader.putReflectionMethod(newDynName.replace('/', '.'), restactMethod);
|
||||||
Field tmpentrysfield = HttpServlet.class.getDeclaredField("_actionmap");
|
Field tmpEntrysField = HttpServlet.class.getDeclaredField("_actionmap");
|
||||||
tmpentrysfield.setAccessible(true);
|
tmpEntrysField.setAccessible(true);
|
||||||
HashMap<String, HttpServlet.ActionEntry> innerEntryMap = (HashMap) restactMethod.invoke(obj);
|
HashMap<String, HttpServlet.ActionEntry> innerEntryMap = (HashMap) restactMethod.invoke(obj);
|
||||||
for (Map.Entry<String, HttpServlet.ActionEntry> en : innerEntryMap.entrySet()) {
|
for (Map.Entry<String, HttpServlet.ActionEntry> en : innerEntryMap.entrySet()) {
|
||||||
Method m = mappingurlToMethod.get(en.getKey());
|
Method m = mappingurlToMethod.get(en.getKey());
|
||||||
@@ -3425,8 +3492,13 @@ public final class Rest {
|
|||||||
en.getValue().annotations = HttpServlet.ActionEntry.annotations(m);
|
en.getValue().annotations = HttpServlet.ActionEntry.annotations(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmpentrysfield.set(obj, innerEntryMap);
|
tmpEntrysField.set(obj, innerEntryMap);
|
||||||
RedkaleClassLoader.putReflectionField(HttpServlet.class.getName(), tmpentrysfield);
|
RedkaleClassLoader.putReflectionField(HttpServlet.class.getName(), tmpEntrysField);
|
||||||
|
|
||||||
|
Field nonblockField = Servlet.class.getDeclaredField("_nonBlocking");
|
||||||
|
nonblockField.setAccessible(true);
|
||||||
|
nonblockField.set(obj, parentNonBlocking == null ? true : parentNonBlocking);
|
||||||
|
RedkaleClassLoader.putReflectionField(Servlet.class.getName(), nonblockField);
|
||||||
return obj;
|
return obj;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RestException(e);
|
throw new RestException(e);
|
||||||
@@ -3557,7 +3629,7 @@ public final class Rest {
|
|||||||
return normal ? name : Utility.md5Hex(name);
|
return normal ? name : Utility.md5Hex(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappingEntry(final boolean serRpcOnly, int methodIndex, RestMapping mapping, final String defModuleName, Method method) {
|
public MappingEntry(final boolean serRpcOnly, int methodIndex, Boolean typeNonBlocking, RestMapping mapping, final String defModuleName, Method method) {
|
||||||
if (mapping == null) {
|
if (mapping == null) {
|
||||||
mapping = DEFAULT__MAPPING;
|
mapping = DEFAULT__MAPPING;
|
||||||
}
|
}
|
||||||
@@ -3588,6 +3660,22 @@ public final class Rest {
|
|||||||
this.existsPound = pound;
|
this.existsPound = pound;
|
||||||
this.newMethodName = formatMappingName(this.name.replace('/', '$').replace('.', '_').replace('-', '_'));
|
this.newMethodName = formatMappingName(this.name.replace('/', '$').replace('.', '_').replace('-', '_'));
|
||||||
this.newActionClassName = "_Dyn_" + this.newMethodName + "_ActionHttpServlet";
|
this.newActionClassName = "_Dyn_" + this.newMethodName + "_ActionHttpServlet";
|
||||||
|
|
||||||
|
NonBlocking non = method.getAnnotation(NonBlocking.class);
|
||||||
|
Boolean nonFlag = non == null ? typeNonBlocking : (Boolean) non.value(); //显注在方法优先级大于类
|
||||||
|
if (nonFlag == null) {
|
||||||
|
if (CompletionStage.class.isAssignableFrom(method.getReturnType())) {
|
||||||
|
nonFlag = true;
|
||||||
|
} else {
|
||||||
|
for (Parameter mp : method.getParameters()) {
|
||||||
|
if (CompletionHandler.class.isAssignableFrom(mp.getType())) {
|
||||||
|
nonFlag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.nonBlocking = nonFlag == null ? false : nonFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int methodIdx; // _paramtypes 的下标,从0开始
|
public final int methodIdx; // _paramtypes 的下标,从0开始
|
||||||
@@ -3608,6 +3696,8 @@ public final class Rest {
|
|||||||
|
|
||||||
public final String[] methods;
|
public final String[] methods;
|
||||||
|
|
||||||
|
public final boolean nonBlocking;
|
||||||
|
|
||||||
public final boolean rpconly;
|
public final boolean rpconly;
|
||||||
|
|
||||||
public final boolean auth;
|
public final boolean auth;
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
final void preInit(Application application, HttpContext context, AnyValue conf) {
|
final void preInit(Application application, HttpContext context, AnyValue conf) {
|
||||||
|
this._nonBlocking = true;
|
||||||
if (this.textConvert == null) {
|
if (this.textConvert == null) {
|
||||||
this.textConvert = jsonConvert;
|
this.textConvert = jsonConvert;
|
||||||
}
|
}
|
||||||
@@ -218,6 +219,7 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override //在IOThread中执行
|
@Override //在IOThread中执行
|
||||||
|
@NonBlocking
|
||||||
public final void execute(final HttpRequest request, final HttpResponse response) throws IOException {
|
public final void execute(final HttpRequest request, final HttpResponse response) throws IOException {
|
||||||
final boolean debug = logger.isLoggable(Level.FINEST);
|
final boolean debug = logger.isLoggable(Level.FINEST);
|
||||||
if (!request.isWebSocket()) {
|
if (!request.isWebSocket()) {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.nio.channels.CompletionHandler;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
import org.redkale.annotation.ConstructorParameters;
|
import org.redkale.annotation.ConstructorParameters;
|
||||||
import static org.redkale.asm.Opcodes.*;
|
|
||||||
import org.redkale.asm.*;
|
import org.redkale.asm.*;
|
||||||
import static org.redkale.asm.Opcodes.*;
|
import static org.redkale.asm.Opcodes.*;
|
||||||
import org.redkale.convert.bson.*;
|
import org.redkale.convert.bson.*;
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ public class SncpClientRequest extends ClientRequest {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "_" + Objects.hashCode(this) + "{"
|
return getClass().getSimpleName() + "_" + Objects.hashCode(this) + "{"
|
||||||
+ "header=" + header
|
+ "header=" + header + ", seqid =" + seqid
|
||||||
+ ", seqid =" + seqid
|
|
||||||
+ ", body=[" + (bodyContent == null ? -1 : bodyContent.length) + "]"
|
+ ", body=[" + (bodyContent == null ? -1 : bodyContent.length) + "]"
|
||||||
+ "}";
|
+ "}";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ public class SncpDispatcherServlet extends DispatcherServlet<Uint128, SncpContex
|
|||||||
|
|
||||||
private final byte[] pongBytes = Sncp.getPongBytes();
|
private final byte[] pongBytes = Sncp.getPongBytes();
|
||||||
|
|
||||||
|
protected SncpDispatcherServlet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addServlet(SncpServlet servlet, Object attachment, AnyValue conf, Uint128... mappings) {
|
public void addServlet(SncpServlet servlet, Object attachment, AnyValue conf, Uint128... mappings) {
|
||||||
sncplock.lock();
|
sncplock.lock();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import java.util.*;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
import org.redkale.annotation.Resource;
|
import org.redkale.annotation.*;
|
||||||
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
||||||
import org.redkale.asm.*;
|
import org.redkale.asm.*;
|
||||||
import static org.redkale.asm.Opcodes.*;
|
import static org.redkale.asm.Opcodes.*;
|
||||||
@@ -164,6 +164,8 @@ public final class SncpDynServlet extends SncpServlet {
|
|||||||
|
|
||||||
public Creator<SncpAsyncHandler> handlerCreator;
|
public Creator<SncpAsyncHandler> handlerCreator;
|
||||||
|
|
||||||
|
protected boolean nonBlocking;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected BsonConvert convert;
|
protected BsonConvert convert;
|
||||||
|
|
||||||
@@ -619,9 +621,14 @@ public final class SncpDynServlet extends SncpServlet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NonBlocking non = method.getAnnotation(NonBlocking.class);
|
||||||
|
if (non == null) {
|
||||||
|
non = service.getClass().getAnnotation(NonBlocking.class);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
SncpServletAction instance = (SncpServletAction) newClazz.getDeclaredConstructor().newInstance();
|
SncpServletAction instance = (SncpServletAction) newClazz.getDeclaredConstructor().newInstance();
|
||||||
instance.method = method;
|
instance.method = method;
|
||||||
|
instance.nonBlocking = non == null ? false : non.value();
|
||||||
java.lang.reflect.Type[] types = new java.lang.reflect.Type[originalParamTypes.length + 1];
|
java.lang.reflect.Type[] types = new java.lang.reflect.Type[originalParamTypes.length + 1];
|
||||||
types[0] = originalReturnType;
|
types[0] = originalReturnType;
|
||||||
System.arraycopy(originalParamTypes, 0, types, 1, originalParamTypes.length);
|
System.arraycopy(originalParamTypes, 0, types, 1, originalParamTypes.length);
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ public class SncpHeader {
|
|||||||
public SncpHeader() {
|
public SncpHeader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SncpHeader(InetSocketAddress clientSncpAddress) {
|
|
||||||
this.addrBytes = clientSncpAddress == null ? new byte[4] : clientSncpAddress.getAddress().getAddress();
|
|
||||||
this.addrPort = clientSncpAddress == null ? 0 : clientSncpAddress.getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SncpHeader(InetSocketAddress clientSncpAddress, Uint128 serviceid, Uint128 actionid) {
|
public SncpHeader(InetSocketAddress clientSncpAddress, Uint128 serviceid, Uint128 actionid) {
|
||||||
this.addrBytes = clientSncpAddress == null ? new byte[4] : clientSncpAddress.getAddress().getAddress();
|
this.addrBytes = clientSncpAddress == null ? new byte[4] : clientSncpAddress.getAddress().getAddress();
|
||||||
this.addrPort = clientSncpAddress == null ? 0 : clientSncpAddress.getPort();
|
this.addrPort = clientSncpAddress == null ? 0 : clientSncpAddress.getPort();
|
||||||
@@ -145,64 +140,32 @@ public class SncpHeader {
|
|||||||
return seqid;
|
return seqid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSeqid(Long seqid) {
|
|
||||||
this.seqid = seqid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uint128 getServiceid() {
|
public Uint128 getServiceid() {
|
||||||
return serviceid;
|
return serviceid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServiceid(Uint128 serviceid) {
|
|
||||||
this.serviceid = serviceid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getServiceVersion() {
|
public int getServiceVersion() {
|
||||||
return serviceVersion;
|
return serviceVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServiceVersion(int serviceVersion) {
|
|
||||||
this.serviceVersion = serviceVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uint128 getActionid() {
|
public Uint128 getActionid() {
|
||||||
return actionid;
|
return actionid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActionid(Uint128 actionid) {
|
|
||||||
this.actionid = actionid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getAddrBytes() {
|
public byte[] getAddrBytes() {
|
||||||
return addrBytes;
|
return addrBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAddrBytes(byte[] addrBytes) {
|
|
||||||
this.addrBytes = addrBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAddrPort() {
|
public int getAddrPort() {
|
||||||
return addrPort;
|
return addrPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAddrPort(int addrPort) {
|
|
||||||
this.addrPort = addrPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBodyLength() {
|
public int getBodyLength() {
|
||||||
return bodyLength;
|
return bodyLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBodyLength(int bodyLength) {
|
|
||||||
this.bodyLength = bodyLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRetcode() {
|
public int getRetcode() {
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRetcode(int retcode) {
|
|
||||||
this.retcode = retcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.net.sncp;
|
package org.redkale.net.sncp;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import org.redkale.convert.bson.BsonWriter;
|
import org.redkale.convert.bson.BsonWriter;
|
||||||
import org.redkale.net.Response;
|
import org.redkale.net.Response;
|
||||||
import static org.redkale.net.sncp.SncpHeader.HEADER_SIZE;
|
import static org.redkale.net.sncp.SncpHeader.HEADER_SIZE;
|
||||||
@@ -66,6 +67,26 @@ public class SncpResponse extends Response<SncpContext, SncpRequest> {
|
|||||||
return super.recycle();
|
return super.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExecutorService getWorkExecutor() {
|
||||||
|
return super.getWorkExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateNonBlocking(boolean nonBlocking) {
|
||||||
|
super.updateNonBlocking(nonBlocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean inNonBlocking() {
|
||||||
|
return super.inNonBlocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finishError(Throwable t) {
|
||||||
|
finish(RETCODE_THROWEXCEPTION, null);
|
||||||
|
}
|
||||||
|
|
||||||
public void finish(final int retcode, final BsonWriter out) {
|
public void finish(final int retcode, final BsonWriter out) {
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
final ByteArray buffer = new ByteArray(HEADER_SIZE);
|
final ByteArray buffer = new ByteArray(HEADER_SIZE);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public abstract class SncpServlet extends Servlet<SncpContext, SncpRequest, Sncp
|
|||||||
this.serviceName = serviceResourceName;
|
this.serviceName = serviceResourceName;
|
||||||
this.serviceType = serviceResourceType;
|
this.serviceType = serviceResourceType;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
|
this._nonBlocking = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Service getService() {
|
public Service getService() {
|
||||||
|
|||||||
Reference in New Issue
Block a user