pipelineWrite
This commit is contained in:
@@ -205,6 +205,16 @@ public abstract class AsyncConnection implements Channel, AutoCloseable {
|
|||||||
return ioWriteThread;
|
return ioWriteThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract AsyncConnection pipelineHandler(CompletionHandler handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速发送
|
||||||
|
*
|
||||||
|
* @see org.redkale.net.AsyncNioConnection#pipelineWrite(java.util.function.Consumer)
|
||||||
|
* @param consumers Consumer
|
||||||
|
*/
|
||||||
|
public abstract void pipelineWrite(Consumer<ByteArray> consumer);
|
||||||
|
|
||||||
public abstract boolean isTCP();
|
public abstract boolean isTCP();
|
||||||
|
|
||||||
public abstract boolean shutdownInput();
|
public abstract boolean shutdownInput();
|
||||||
|
|||||||
@@ -138,6 +138,10 @@ public class AsyncIOThread extends WorkThread {
|
|||||||
selector.wakeup();
|
selector.wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void wakeup() {
|
||||||
|
selector.wakeup();
|
||||||
|
}
|
||||||
|
|
||||||
public Supplier<ByteBuffer> getBufferSupplier() {
|
public Supplier<ByteBuffer> getBufferSupplier() {
|
||||||
return bufferSupplier;
|
return bufferSupplier;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ import java.net.SocketAddress;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.*;
|
import java.nio.channels.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import org.redkale.util.ByteArray;
|
||||||
import org.redkale.util.ByteBufferWriter;
|
import org.redkale.util.ByteBufferWriter;
|
||||||
|
import org.redkale.util.RedkaleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
@@ -37,6 +40,13 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
protected CompletionHandler<Integer, ByteBuffer> readCompletionHandler;
|
protected CompletionHandler<Integer, ByteBuffer> readCompletionHandler;
|
||||||
|
|
||||||
protected SelectionKey readKey;
|
protected SelectionKey readKey;
|
||||||
|
|
||||||
|
// ------------------------------ pipeline写操作 ------------------------------------
|
||||||
|
protected ByteArray pipelineWriteArray;
|
||||||
|
|
||||||
|
protected Queue<Consumer<ByteArray>> pipelineWriteQueue;
|
||||||
|
|
||||||
|
protected CompletionHandler pipelineWriteHandler;
|
||||||
// -------------------------------- 写操作 --------------------------------------
|
// -------------------------------- 写操作 --------------------------------------
|
||||||
protected byte[] writeByteTuple1Array;
|
protected byte[] writeByteTuple1Array;
|
||||||
|
|
||||||
@@ -84,12 +94,6 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
return remoteAddress;
|
return remoteAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public <A> AsyncConnection fastHandler(CompletionHandler<Integer, ? super A> handler) {
|
|
||||||
// Objects.requireNonNull(handler);
|
|
||||||
// this.writeFastHandler = (CompletionHandler) handler;
|
|
||||||
// return this;
|
|
||||||
// }
|
|
||||||
@Override
|
@Override
|
||||||
protected void startHandshake(final Consumer<Throwable> callback) {
|
protected void startHandshake(final Consumer<Throwable> callback) {
|
||||||
ioReadThread.register(t -> super.startHandshake(callback));
|
ioReadThread.register(t -> super.startHandshake(callback));
|
||||||
@@ -158,6 +162,66 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
doRead(this.ioReadThread.inCurrThread());
|
doRead(this.ioReadThread.inCurrThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final AsyncConnection pipelineHandler(CompletionHandler handler) {
|
||||||
|
if (!clientMode) {
|
||||||
|
throw new RedkaleException("fast-writer only for client connection");
|
||||||
|
}
|
||||||
|
this.pipelineWriteHandler = Objects.requireNonNull(handler);
|
||||||
|
this.pipelineWriteArray = new ByteArray();
|
||||||
|
this.pipelineWriteQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void pipelineWrite(Consumer<ByteArray> consumer) {
|
||||||
|
if (pipelineWriteHandler == null) {
|
||||||
|
throw new RedkaleException("fast-writer handler is null");
|
||||||
|
}
|
||||||
|
this.pipelineWriteQueue.offer(consumer);
|
||||||
|
if (writeKey == null) {
|
||||||
|
this.ioWriteThread.register(this::pipelineWriteRegister);
|
||||||
|
} else {
|
||||||
|
this.writeCompletionHandler = this.pipelineWriteHandler;
|
||||||
|
writeKey.interestOps(writeKey.interestOps() | SelectionKey.OP_WRITE);
|
||||||
|
this.ioWriteThread.wakeup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pipelineWriteRegister(Selector selector) {
|
||||||
|
try {
|
||||||
|
if (writeKey == null) {
|
||||||
|
writeKey = keyFor(selector);
|
||||||
|
}
|
||||||
|
if (writeKey == null) {
|
||||||
|
writeKey = implRegister(selector, SelectionKey.OP_WRITE);
|
||||||
|
writeKey.attach(this);
|
||||||
|
} else {
|
||||||
|
writeKey.interestOps(writeKey.interestOps() | SelectionKey.OP_WRITE);
|
||||||
|
}
|
||||||
|
// writeCompletionHandler必须赋值,不然会跳过doWrite
|
||||||
|
this.writeCompletionHandler = this.pipelineWriteHandler;
|
||||||
|
} catch (ClosedChannelException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
this.pipelineWriteQueue.clear();
|
||||||
|
handleWrite(0, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pipelineWritePrepare() {
|
||||||
|
ByteArray array = this.pipelineWriteArray.clear();
|
||||||
|
Consumer<ByteArray> func;
|
||||||
|
while ((func = pipelineWriteQueue.poll()) != null) {
|
||||||
|
func.accept(array);
|
||||||
|
}
|
||||||
|
this.writePending = true;
|
||||||
|
this.writeAttachment = null;
|
||||||
|
this.writeByteTuple1Array = array.content();
|
||||||
|
this.writeByteTuple1Offset = array.offset();
|
||||||
|
this.writeByteTuple1Length = array.length();
|
||||||
|
this.writeCompletionHandler = this.pipelineWriteHandler;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(
|
public void write(
|
||||||
byte[] headerContent,
|
byte[] headerContent,
|
||||||
@@ -300,6 +364,10 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
boolean hasRemain = true;
|
boolean hasRemain = true;
|
||||||
boolean writeCompleted = true;
|
boolean writeCompleted = true;
|
||||||
boolean error = false;
|
boolean error = false;
|
||||||
|
// pipelineWrite
|
||||||
|
if (clientMode && pipelineWriteArray != null && writeByteBuffer == null && writeByteBuffers == null) {
|
||||||
|
pipelineWritePrepare();
|
||||||
|
}
|
||||||
int batchOffset = writeBuffersOffset;
|
int batchOffset = writeBuffersOffset;
|
||||||
int batchLength = writeBuffersLength;
|
int batchLength = writeBuffersLength;
|
||||||
while (hasRemain) { // 必须要将buffer写完为止
|
while (hasRemain) { // 必须要将buffer写完为止
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public abstract class ClientConnection<R extends ClientRequest, P extends Client
|
|||||||
public ClientConnection(Client<? extends ClientConnection<R, P>, R, P> client, AsyncConnection channel) {
|
public ClientConnection(Client<? extends ClientConnection<R, P>, R, P> client, AsyncConnection channel) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.codec = createCodec();
|
this.codec = createCodec();
|
||||||
this.channel = channel.beforeCloseListener(this); // .fastHandler(writeHandler);
|
this.channel = channel.beforeCloseListener(this); // .pipelineHandler(writeHandler);
|
||||||
this.writeBuffer = channel.pollWriteBuffer();
|
this.writeBuffer = channel.pollWriteBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ public abstract class ClientConnection<R extends ClientRequest, P extends Client
|
|||||||
for (ClientFuture respFuture : respFutures) {
|
for (ClientFuture respFuture : respFutures) {
|
||||||
offerRespFuture(respFuture);
|
offerRespFuture(respFuture);
|
||||||
}
|
}
|
||||||
sendRequestToChannel(respFutures);
|
sendRequestInLocking(respFutures);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
writeLock.unlock();
|
writeLock.unlock();
|
||||||
@@ -158,6 +158,10 @@ public abstract class ClientConnection<R extends ClientRequest, P extends Client
|
|||||||
return respFutures;
|
return respFutures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void sendRequestInLocking(ClientFuture... respFutures) {
|
||||||
|
sendRequestToChannel(respFutures);
|
||||||
|
}
|
||||||
|
|
||||||
protected final void sendRequestToChannel(ClientFuture... respFutures) {
|
protected final void sendRequestToChannel(ClientFuture... respFutures) {
|
||||||
// 发送请求数据包
|
// 发送请求数据包
|
||||||
writeArray.clear();
|
writeArray.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user