优化ClientWriteIOThread
This commit is contained in:
@@ -320,7 +320,7 @@ public abstract class AsyncConnection implements ChannelContext, Channel, AutoCl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
CompletionHandler<Integer, Void> newhandler = new CompletionHandler<Integer, Void>() {
|
CompletionHandler<Integer, Void> newHandler = new CompletionHandler<Integer, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void completed(Integer result, Void attachment) {
|
public void completed(Integer result, Void attachment) {
|
||||||
offerWriteBuffer(buffer);
|
offerWriteBuffer(buffer);
|
||||||
@@ -333,7 +333,7 @@ public abstract class AsyncConnection implements ChannelContext, Channel, AutoCl
|
|||||||
handler.failed(exc, attachment);
|
handler.failed(exc, attachment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
write(buffer, null, newhandler);
|
write(buffer, null, newHandler);
|
||||||
} else {
|
} else {
|
||||||
ByteBufferWriter writer = ByteBufferWriter.create(sslEngine == null ? writeBufferSupplier : () -> pollWriteSSLBuffer(), buffer);
|
ByteBufferWriter writer = ByteBufferWriter.create(sslEngine == null ? writeBufferSupplier : () -> pollWriteSSLBuffer(), buffer);
|
||||||
writer.put(headerContent, headerOffset, headerLength);
|
writer.put(headerContent, headerOffset, headerLength);
|
||||||
@@ -344,7 +344,7 @@ public abstract class AsyncConnection implements ChannelContext, Channel, AutoCl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final ByteBuffer[] buffers = writer.toBuffers();
|
final ByteBuffer[] buffers = writer.toBuffers();
|
||||||
CompletionHandler<Integer, Void> newhandler = new CompletionHandler<Integer, Void>() {
|
CompletionHandler<Integer, Void> newHandler = new CompletionHandler<Integer, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void completed(Integer result, Void attachment) {
|
public void completed(Integer result, Void attachment) {
|
||||||
offerWriteBuffer(buffers);
|
offerWriteBuffer(buffers);
|
||||||
@@ -357,7 +357,7 @@ public abstract class AsyncConnection implements ChannelContext, Channel, AutoCl
|
|||||||
handler.failed(exc, attachment);
|
handler.failed(exc, attachment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
write(buffers, null, newhandler);
|
write(buffers, null, newHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ public abstract class AsyncConnection implements ChannelContext, Channel, AutoCl
|
|||||||
handler.completed(0, attachment);
|
handler.completed(0, attachment);
|
||||||
} else {
|
} else {
|
||||||
ByteBuffer[] srcs = writer.toBuffers();
|
ByteBuffer[] srcs = writer.toBuffers();
|
||||||
CompletionHandler<Integer, ? super A> newhandler = new CompletionHandler<Integer, A>() {
|
CompletionHandler<Integer, ? super A> newHandler = new CompletionHandler<Integer, A>() {
|
||||||
@Override
|
@Override
|
||||||
public void completed(Integer result, A attachment) {
|
public void completed(Integer result, A attachment) {
|
||||||
offerWriteBuffer(srcs);
|
offerWriteBuffer(srcs);
|
||||||
@@ -398,9 +398,9 @@ public abstract class AsyncConnection implements ChannelContext, Channel, AutoCl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (srcs.length == 1) {
|
if (srcs.length == 1) {
|
||||||
write(srcs[0], attachment, newhandler);
|
write(srcs[0], attachment, newHandler);
|
||||||
} else {
|
} else {
|
||||||
write(srcs, attachment, newhandler);
|
write(srcs, attachment, newHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,6 @@ public class AsyncIOThread extends WorkThread {
|
|||||||
key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
|
key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
|
||||||
conn.doRead(true);
|
conn.doRead(true);
|
||||||
} else if (conn.writeCompletionHandler != null && key.isWritable()) {
|
} else if (conn.writeCompletionHandler != null && key.isWritable()) {
|
||||||
conn.currWriteInvoker = 0;
|
|
||||||
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
|
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
|
||||||
conn.doWrite(true);
|
conn.doWrite(true);
|
||||||
}
|
}
|
||||||
@@ -186,7 +185,6 @@ public class AsyncIOThread extends WorkThread {
|
|||||||
key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); //不放开这行,在CompletableFuture时容易ReadPending
|
key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); //不放开这行,在CompletableFuture时容易ReadPending
|
||||||
conn.doRead(true);
|
conn.doRead(true);
|
||||||
} else if (conn.writeCompletionHandler != null && key.isWritable()) {
|
} else if (conn.writeCompletionHandler != null && key.isWritable()) {
|
||||||
conn.currWriteInvoker = 0;
|
|
||||||
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
|
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
|
||||||
conn.doWrite(true);
|
conn.doWrite(true);
|
||||||
} else if (key.isConnectable()) {
|
} else if (key.isConnectable()) {
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
|
|
||||||
protected int writeTimeoutSeconds;
|
protected int writeTimeoutSeconds;
|
||||||
|
|
||||||
int currWriteInvoker;
|
|
||||||
|
|
||||||
protected byte[] writeByteTuple1Array;
|
protected byte[] writeByteTuple1Array;
|
||||||
|
|
||||||
protected int writeByteTuple1Offset;
|
protected int writeByteTuple1Offset;
|
||||||
@@ -154,10 +152,10 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
}
|
}
|
||||||
this.readPending = true;
|
this.readPending = true;
|
||||||
if (this.readTimeoutSeconds > 0) {
|
if (this.readTimeoutSeconds > 0) {
|
||||||
AsyncNioCompletionHandler newhandler = this.readTimeoutCompletionHandler;
|
AsyncNioCompletionHandler newHandler = this.readTimeoutCompletionHandler;
|
||||||
newhandler.handler(handler, this.readByteBuffer); // new AsyncNioCompletionHandler(handler, this.readByteBuffer);
|
newHandler.handler(handler, this.readByteBuffer); // new AsyncNioCompletionHandler(handler, this.readByteBuffer);
|
||||||
this.readCompletionHandler = newhandler;
|
this.readCompletionHandler = newHandler;
|
||||||
newhandler.timeoutFuture = ioGroup.scheduleTimeout(newhandler, this.readTimeoutSeconds, TimeUnit.SECONDS);
|
newHandler.timeoutFuture = ioGroup.scheduleTimeout(newHandler, this.readTimeoutSeconds, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
this.readCompletionHandler = handler;
|
this.readCompletionHandler = handler;
|
||||||
}
|
}
|
||||||
@@ -196,14 +194,14 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
this.writeByteTuple2Attachment = bodyAttachment;
|
this.writeByteTuple2Attachment = bodyAttachment;
|
||||||
this.writeAttachment = null;
|
this.writeAttachment = null;
|
||||||
if (this.writeTimeoutSeconds > 0) {
|
if (this.writeTimeoutSeconds > 0) {
|
||||||
AsyncNioCompletionHandler newhandler = this.writeTimeoutCompletionHandler;
|
AsyncNioCompletionHandler newHandler = this.writeTimeoutCompletionHandler;
|
||||||
newhandler.handler(handler, null); // new AsyncNioCompletionHandler(handler, null);
|
newHandler.handler(handler, null); // new AsyncNioCompletionHandler(handler, null);
|
||||||
this.writeCompletionHandler = newhandler;
|
this.writeCompletionHandler = newHandler;
|
||||||
newhandler.timeoutFuture = ioGroup.scheduleTimeout(newhandler, this.writeTimeoutSeconds, TimeUnit.SECONDS);
|
newHandler.timeoutFuture = ioGroup.scheduleTimeout(newHandler, this.writeTimeoutSeconds, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
AsyncNioCompletionHandler newhandler = this.writeTimeoutCompletionHandler;
|
AsyncNioCompletionHandler newHandler = this.writeTimeoutCompletionHandler;
|
||||||
newhandler.handler(handler, null); // new AsyncNioCompletionHandler(handler, null);
|
newHandler.handler(handler, null); // new AsyncNioCompletionHandler(handler, null);
|
||||||
this.writeCompletionHandler = newhandler;
|
this.writeCompletionHandler = newHandler;
|
||||||
}
|
}
|
||||||
doWrite(true); //如果不是true,则bodyCallback的执行可能会切换线程
|
doWrite(true); //如果不是true,则bodyCallback的执行可能会切换线程
|
||||||
}
|
}
|
||||||
@@ -224,14 +222,14 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
this.writeByteBuffer = src;
|
this.writeByteBuffer = src;
|
||||||
this.writeAttachment = attachment;
|
this.writeAttachment = attachment;
|
||||||
if (this.writeTimeoutSeconds > 0) {
|
if (this.writeTimeoutSeconds > 0) {
|
||||||
AsyncNioCompletionHandler newhandler = this.writeTimeoutCompletionHandler;
|
AsyncNioCompletionHandler newHandler = this.writeTimeoutCompletionHandler;
|
||||||
newhandler.handler(handler, attachment); // new AsyncNioCompletionHandler(handler, attachment);
|
newHandler.handler(handler, attachment); // new AsyncNioCompletionHandler(handler, attachment);
|
||||||
this.writeCompletionHandler = newhandler;
|
this.writeCompletionHandler = newHandler;
|
||||||
newhandler.timeoutFuture = ioGroup.scheduleTimeout(newhandler, this.writeTimeoutSeconds, TimeUnit.SECONDS);
|
newHandler.timeoutFuture = ioGroup.scheduleTimeout(newHandler, this.writeTimeoutSeconds, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
this.writeCompletionHandler = (CompletionHandler) handler;
|
this.writeCompletionHandler = (CompletionHandler) handler;
|
||||||
}
|
}
|
||||||
doWrite(true); // || !client || currWriteInvoker < MAX_INVOKER_ONSTACK // !client && ioThread.workExecutor == null
|
doWrite(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -252,14 +250,14 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
this.writeLength = length;
|
this.writeLength = length;
|
||||||
this.writeAttachment = attachment;
|
this.writeAttachment = attachment;
|
||||||
if (this.writeTimeoutSeconds > 0) {
|
if (this.writeTimeoutSeconds > 0) {
|
||||||
AsyncNioCompletionHandler newhandler = this.writeTimeoutCompletionHandler;
|
AsyncNioCompletionHandler newHandler = this.writeTimeoutCompletionHandler;
|
||||||
newhandler.handler(handler, attachment); // new AsyncNioCompletionHandler(handler, attachment);
|
newHandler.handler(handler, attachment); // new AsyncNioCompletionHandler(handler, attachment);
|
||||||
this.writeCompletionHandler = newhandler;
|
this.writeCompletionHandler = newHandler;
|
||||||
newhandler.timeoutFuture = ioGroup.scheduleTimeout(newhandler, this.writeTimeoutSeconds, TimeUnit.SECONDS);
|
newHandler.timeoutFuture = ioGroup.scheduleTimeout(newHandler, this.writeTimeoutSeconds, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
this.writeCompletionHandler = (CompletionHandler) handler;
|
this.writeCompletionHandler = (CompletionHandler) handler;
|
||||||
}
|
}
|
||||||
doWrite(true); // || !client || currWriteInvoker < MAX_INVOKER_ONSTACK // !client && ioThread.workExecutor == null
|
doWrite(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doRead(boolean direct) {
|
public void doRead(boolean direct) {
|
||||||
@@ -303,9 +301,6 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
boolean hasRemain = true;
|
boolean hasRemain = true;
|
||||||
boolean writeCompleted = true;
|
boolean writeCompleted = true;
|
||||||
if (invokeDirect) {
|
|
||||||
currWriteInvoker++;
|
|
||||||
}
|
|
||||||
while (invokeDirect && hasRemain) { //必须要将buffer写完为止
|
while (invokeDirect && hasRemain) { //必须要将buffer写完为止
|
||||||
if (writeByteTuple1Array != null) {
|
if (writeByteTuple1Array != null) {
|
||||||
final ByteBuffer buffer = pollWriteBuffer();
|
final ByteBuffer buffer = pollWriteBuffer();
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public class ClientWriteIOThread extends ClientIOThread {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
final ByteBuffer buffer = getBufferSupplier().get();
|
||||||
|
final int capacity = buffer.capacity();
|
||||||
while (!isClosed()) {
|
while (!isClosed()) {
|
||||||
ClientEntity entity;
|
ClientEntity entity;
|
||||||
try {
|
try {
|
||||||
@@ -44,7 +46,14 @@ public class ClientWriteIOThread extends ClientIOThread {
|
|||||||
ByteArray rw = conn.writeArray;
|
ByteArray rw = conn.writeArray;
|
||||||
rw.clear();
|
rw.clear();
|
||||||
request.accept(conn, rw);
|
request.accept(conn, rw);
|
||||||
conn.channel.write(rw, conn.writeHandler);
|
if (rw.length() <= capacity) {
|
||||||
|
buffer.clear();
|
||||||
|
buffer.put(rw.content(), 0, rw.length());
|
||||||
|
buffer.flip();
|
||||||
|
conn.channel.write(buffer, null, conn.writeHandler);
|
||||||
|
} else {
|
||||||
|
conn.channel.write(rw, conn.writeHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user