ClientConnection优化临时方案
This commit is contained in:
@@ -380,9 +380,9 @@ abstract class AsyncNioConnection extends AsyncConnection {
|
|||||||
|
|
||||||
if (writeCount == 0) {
|
if (writeCount == 0) {
|
||||||
if (hasRemain) {
|
if (hasRemain) {
|
||||||
//writeCompleted = false;
|
writeCompleted = false;
|
||||||
//writeTotal = totalCount;
|
writeTotal = totalCount;
|
||||||
continue; //要全部输出完才返回
|
//continue; //要全部输出完才返回
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (writeCount < 0) {
|
} else if (writeCount < 0) {
|
||||||
|
|||||||
@@ -57,10 +57,47 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completed(Integer result, ClientConnection attachment) {
|
public void completed(Integer result, ClientConnection attachment) {
|
||||||
|
if (pauseWriting.get()) { //等待sendHalfWriteInReadThread调用
|
||||||
|
if (!writePending.compareAndSet(true, false)) {
|
||||||
|
completed(0, attachment);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ByteArray array = writeArray;
|
||||||
|
array.clear();
|
||||||
|
ClientFuture<R, P> respFuture;
|
||||||
|
while ((respFuture = requestQueue.poll()) != null) {
|
||||||
|
if (!respFuture.isDone()) {
|
||||||
|
R request = respFuture.request;
|
||||||
|
request.writeTo(attachment, array);
|
||||||
|
if (request.isCompleted()) {
|
||||||
|
doneRequestCounter.increment();
|
||||||
|
} else { //还剩半包没发送完
|
||||||
|
pauseWriting.set(true);
|
||||||
|
currHalfWriteFuture = respFuture;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (array.length() > 0) {
|
||||||
|
if (writeBuffer.capacity() >= array.length()) {
|
||||||
|
writeBuffer.clear();
|
||||||
|
writeBuffer.put(array.content(), 0, array.length());
|
||||||
|
writeBuffer.flip();
|
||||||
|
channel.write(writeBuffer, attachment, this);
|
||||||
|
} else {
|
||||||
|
channel.write(array, attachment, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!writePending.compareAndSet(true, false)) {
|
||||||
|
completed(0, attachment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(Throwable exc, ClientConnection attachment) {
|
public void failed(Throwable exc, ClientConnection attachment) {
|
||||||
|
writePending.set(false);
|
||||||
attachment.dispose(exc);
|
attachment.dispose(exc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -69,7 +106,8 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
|
|
||||||
final ConcurrentLinkedQueue<ClientFuture> pauseRequests = new ConcurrentLinkedQueue<>();
|
final ConcurrentLinkedQueue<ClientFuture> pauseRequests = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
ClientFuture currHalfWriteFuture; //pauseWriting=true,此字段才会有值; pauseWriting=false,此字段值为null
|
//pauseWriting=true,此字段才会有值; pauseWriting=false,此字段值为null
|
||||||
|
ClientFuture currHalfWriteFuture;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Client.AddressConnEntry connEntry;
|
private final Client.AddressConnEntry connEntry;
|
||||||
@@ -78,8 +116,10 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
|
|
||||||
private final ClientCodec<R, P> codec;
|
private final ClientCodec<R, P> codec;
|
||||||
|
|
||||||
|
private final ConcurrentLinkedQueue<ClientFuture<R, P>> requestQueue = new ConcurrentLinkedQueue();
|
||||||
|
|
||||||
//respFutureQueue、respFutureMap二选一, SPSC队列模式
|
//respFutureQueue、respFutureMap二选一, SPSC队列模式
|
||||||
private final ConcurrentLinkedDeque<ClientFuture<R, P>> respFutureQueue = new ConcurrentLinkedDeque<>(); //Utility.unsafe() != null ? new MpscGrowableArrayQueue<>(16, 1 << 16) : new ConcurrentLinkedQueue<>();
|
private final ConcurrentLinkedDeque<ClientFuture<R, P>> respFutureQueue = new ConcurrentLinkedDeque<>();
|
||||||
|
|
||||||
//respFutureQueue、respFutureMap二选一, key: requestid, SPSC模式
|
//respFutureQueue、respFutureMap二选一, key: requestid, SPSC模式
|
||||||
private final ConcurrentHashMap<Serializable, ClientFuture<R, P>> respFutureMap = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Serializable, ClientFuture<R, P>> respFutureMap = new ConcurrentHashMap<>();
|
||||||
@@ -132,24 +172,28 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendRequestInLocking(R request, ClientFuture respFuture) {
|
private void sendRequestInLocking(R request, ClientFuture respFuture) {
|
||||||
//发送请求数据包
|
if (writePending.compareAndSet(false, true)) {
|
||||||
writeArray.clear();
|
//发送请求数据包
|
||||||
request.writeTo(this, writeArray);
|
writeArray.clear();
|
||||||
if (request.isCompleted()) {
|
request.writeTo(this, writeArray);
|
||||||
doneRequestCounter.increment();
|
if (request.isCompleted()) {
|
||||||
} else { //还剩半包没发送完
|
doneRequestCounter.increment();
|
||||||
pauseWriting.set(true);
|
} else { //还剩半包没发送完
|
||||||
currHalfWriteFuture = respFuture;
|
pauseWriting.set(true);
|
||||||
}
|
currHalfWriteFuture = respFuture;
|
||||||
if (writeArray.length() > 0) {
|
|
||||||
if (writeBuffer.capacity() >= writeArray.length()) {
|
|
||||||
writeBuffer.clear();
|
|
||||||
writeBuffer.put(writeArray.content(), 0, writeArray.length());
|
|
||||||
writeBuffer.flip();
|
|
||||||
channel.write(writeBuffer, this, writeHandler);
|
|
||||||
} else {
|
|
||||||
channel.write(writeArray, this, writeHandler);
|
|
||||||
}
|
}
|
||||||
|
if (writeArray.length() > 0) {
|
||||||
|
if (writeBuffer.capacity() >= writeArray.length()) {
|
||||||
|
writeBuffer.clear();
|
||||||
|
writeBuffer.put(writeArray.content(), 0, writeArray.length());
|
||||||
|
writeBuffer.flip();
|
||||||
|
channel.write(writeBuffer, this, writeHandler);
|
||||||
|
} else {
|
||||||
|
channel.write(writeArray, this, writeHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestQueue.add(respFuture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,14 +205,26 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
ClientFuture respFuture = this.currHalfWriteFuture;
|
ClientFuture respFuture = this.currHalfWriteFuture;
|
||||||
if (respFuture != null) {
|
if (respFuture != null) {
|
||||||
this.currHalfWriteFuture = null;
|
this.currHalfWriteFuture = null;
|
||||||
if (halfRequestExc == null) {
|
if (!respFuture.isDone()) {
|
||||||
offerFirstRespFuture(respFuture);
|
if (halfRequestExc == null) {
|
||||||
sendRequestInLocking(request, respFuture);
|
offerFirstRespFuture(respFuture);
|
||||||
} else {
|
ClientFuture future;
|
||||||
codec.responseComplete(true, respFuture, null, halfRequestExc);
|
while ((future = pauseRequests.poll()) != null) {
|
||||||
|
requestQueue.add(future);
|
||||||
|
}
|
||||||
|
sendRequestInLocking(request, respFuture);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
codec.responseComplete(true, respFuture, null, halfRequestExc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!pauseWriting.get() && (respFuture = pauseRequests.poll()) != null) {
|
respFuture = pauseRequests.poll();
|
||||||
|
if (respFuture != null) {
|
||||||
|
ClientFuture future;
|
||||||
|
while ((future = pauseRequests.poll()) != null) {
|
||||||
|
requestQueue.add(future);
|
||||||
|
}
|
||||||
sendRequestInLocking((R) respFuture.getRequest(), respFuture);
|
sendRequestInLocking((R) respFuture.getRequest(), respFuture);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user