Client实现requestid
This commit is contained in:
@@ -34,8 +34,8 @@ public abstract class ClientCodec<R extends ClientRequest, P> {
|
|||||||
//返回true: array会clear, 返回false: buffer会clear
|
//返回true: array会clear, 返回false: buffer会clear
|
||||||
public abstract boolean decodeMessages(ByteBuffer buffer, ByteArray array);
|
public abstract boolean decodeMessages(ByteBuffer buffer, ByteArray array);
|
||||||
|
|
||||||
protected Queue<ClientFuture> responseQueue() {
|
protected Iterator<ClientFuture> responseIterator() {
|
||||||
return connection.responseQueue;
|
return connection.responseQueue2.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ClientResponse<P>> pollMessages() {
|
public List<ClientResponse<P>> pollMessages() {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.net.client;
|
package org.redkale.net.client;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.*;
|
import java.nio.channels.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -51,7 +52,10 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
|
|
||||||
protected final Queue<R> requestQueue = new ArrayDeque<>();
|
protected final Queue<R> requestQueue = new ArrayDeque<>();
|
||||||
|
|
||||||
protected final ArrayDeque<ClientFuture> responseQueue = new ArrayDeque<>();
|
final ArrayDeque<ClientFuture> responseQueue2 = new ArrayDeque<>();
|
||||||
|
|
||||||
|
//key: requestid
|
||||||
|
final HashMap<Serializable, ClientFuture> responseMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
protected final CompletionHandler<Integer, Void> writeHandler = new CompletionHandler<Integer, Void>() {
|
protected final CompletionHandler<Integer, Void> writeHandler = new CompletionHandler<Integer, Void>() {
|
||||||
|
|
||||||
@@ -91,6 +95,10 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isWaitingResponseEmpty() {
|
||||||
|
return responseQueue2.isEmpty() && responseMap.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
protected void resumeWrite() {
|
protected void resumeWrite() {
|
||||||
this.pauseWriting.set(false);
|
this.pauseWriting.set(false);
|
||||||
}
|
}
|
||||||
@@ -99,7 +107,7 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
ClientConnection conn = this;
|
ClientConnection conn = this;
|
||||||
ByteArray rw = conn.writeArray;
|
ByteArray rw = conn.writeArray;
|
||||||
rw.clear();
|
rw.clear();
|
||||||
int pipelines = maxPipelines > 1 ? (maxPipelines - responseQueue.size()) : 1;
|
int pipelines = maxPipelines > 1 ? (maxPipelines - responseQueue2.size() - responseMap.size()) : 1;
|
||||||
if (must && pipelines < 1) {
|
if (must && pipelines < 1) {
|
||||||
pipelines = 1;
|
pipelines = 1;
|
||||||
}
|
}
|
||||||
@@ -120,7 +128,7 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
writeLastRequest = req;
|
writeLastRequest = req;
|
||||||
if (req.canMerge(conn)) {
|
if (req.getRequestid() == null && req.canMerge(conn)) {
|
||||||
R r;
|
R r;
|
||||||
while ((r = requestQueue.poll()) != null) {
|
while ((r = requestQueue.poll()) != null) {
|
||||||
i++;
|
i++;
|
||||||
@@ -179,7 +187,12 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
if (respFuture != null) {
|
if (respFuture != null) {
|
||||||
if (!respFuture.request.isCompleted()) {
|
if (!respFuture.request.isCompleted()) {
|
||||||
if (rs.exc == null) {
|
if (rs.exc == null) {
|
||||||
responseQueue.offerFirst(respFuture);
|
Serializable reqid = respFuture.request.getRequestid();
|
||||||
|
if (reqid == null) {
|
||||||
|
responseQueue2.offerFirst(respFuture);
|
||||||
|
} else {
|
||||||
|
responseMap.put(reqid, respFuture);
|
||||||
|
}
|
||||||
pauseWriting.set(false);
|
pauseWriting.set(false);
|
||||||
return;
|
return;
|
||||||
} else { //异常了需要清掉半包
|
} else { //异常了需要清掉半包
|
||||||
@@ -264,13 +277,14 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
List<ClientResponse<P>> results = codec.pollMessages();
|
List<ClientResponse<P>> results = codec.pollMessages();
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
for (ClientResponse<P> rs : results) {
|
for (ClientResponse<P> rs : results) {
|
||||||
ClientFuture respFuture = responseQueue.poll();
|
Serializable reqid = rs.getRequestid();
|
||||||
|
ClientFuture respFuture = reqid == null ? responseQueue2.poll() : responseMap.remove(reqid);
|
||||||
if (respFuture != null) {
|
if (respFuture != null) {
|
||||||
int mergeCount = respFuture.mergeCount;
|
int mergeCount = respFuture.mergeCount;
|
||||||
completeResponse(rs, respFuture);
|
completeResponse(rs, respFuture);
|
||||||
if (mergeCount > 0) {
|
if (mergeCount > 0) {
|
||||||
for (int i = 0; i < mergeCount; i++) {
|
for (int i = 0; i < mergeCount; i++) {
|
||||||
respFuture = responseQueue.poll();
|
respFuture = reqid == null ? responseQueue2.poll() : responseMap.remove(reqid);
|
||||||
if (respFuture != null) {
|
if (respFuture != null) {
|
||||||
completeResponse(rs, respFuture);
|
completeResponse(rs, respFuture);
|
||||||
}
|
}
|
||||||
@@ -282,7 +296,7 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
|
|
||||||
if (buffer.hasRemaining()) {
|
if (buffer.hasRemaining()) {
|
||||||
decodeResponse(buffer);
|
decodeResponse(buffer);
|
||||||
} else if (responseQueue.isEmpty()) { //队列都已处理完了
|
} else if (isWaitingResponseEmpty()) { //队列都已处理完了
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
channel.setReadBuffer(buffer);
|
channel.setReadBuffer(buffer);
|
||||||
if (readPending.compareAndSet(true, false)) {
|
if (readPending.compareAndSet(true, false)) {
|
||||||
@@ -354,12 +368,17 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeChannelInThread(R request, ClientFuture respFuture) {
|
private void writeChannelInThread(R request, ClientFuture respFuture) {
|
||||||
|
Serializable reqid = request.getRequestid();
|
||||||
//保证顺序一致
|
//保证顺序一致
|
||||||
if (client.closeRequest != null && respFuture.request == client.closeRequest) {
|
if (client.closeRequest != null && respFuture.request == client.closeRequest) {
|
||||||
responseQueue.offer(ClientFuture.EMPTY);
|
responseQueue2.offer(ClientFuture.EMPTY);
|
||||||
} else {
|
} else {
|
||||||
request.respFuture = respFuture;
|
request.respFuture = respFuture;
|
||||||
responseQueue.offer(respFuture);
|
if (reqid == null) {
|
||||||
|
responseQueue2.offer(respFuture);
|
||||||
|
} else {
|
||||||
|
responseMap.put(reqid, respFuture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
requestQueue.offer(request);
|
requestQueue.offer(request);
|
||||||
if (isAuthenticated() && client.reqWritedCounter != null) {
|
if (isAuthenticated() && client.reqWritedCounter != null) {
|
||||||
@@ -406,9 +425,17 @@ public abstract class ClientConnection<R extends ClientRequest, P> implements Co
|
|||||||
CompletableFuture f;
|
CompletableFuture f;
|
||||||
respWaitingCounter.reset();
|
respWaitingCounter.reset();
|
||||||
WorkThread thread = channel.getAsyncIOThread();
|
WorkThread thread = channel.getAsyncIOThread();
|
||||||
while ((f = responseQueue.poll()) != null) {
|
if (!responseQueue2.isEmpty()) {
|
||||||
CompletableFuture future = f;
|
while ((f = responseQueue2.poll()) != null) {
|
||||||
thread.runWork(() -> future.completeExceptionally(e));
|
CompletableFuture future = f;
|
||||||
|
thread.runWork(() -> future.completeExceptionally(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!responseMap.isEmpty()) {
|
||||||
|
responseMap.forEach((key, future) -> {
|
||||||
|
responseMap.remove(key);
|
||||||
|
thread.runWork(() -> future.completeExceptionally(e));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,10 +72,14 @@ public class ClientFuture<T> extends CompletableFuture<T> implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runTimeout() {
|
private void runTimeout() {
|
||||||
Queue<ClientFuture> responseQueue = conn.responseQueue;
|
Queue<ClientFuture> responseQueue = conn.responseQueue2;
|
||||||
if (responseQueue != null) {
|
if (responseQueue != null) {
|
||||||
responseQueue.remove(this);
|
responseQueue.remove(this);
|
||||||
}
|
}
|
||||||
|
if (request.getRequestid() != null) {
|
||||||
|
conn.responseMap.remove(request.getRequestid());
|
||||||
|
}
|
||||||
|
|
||||||
TimeoutException ex = new TimeoutException();
|
TimeoutException ex = new TimeoutException();
|
||||||
WorkThread workThread = null;
|
WorkThread workThread = null;
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.net.client;
|
package org.redkale.net.client;
|
||||||
|
|
||||||
import java.util.function.*;
|
import java.io.Serializable;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import org.redkale.net.WorkThread;
|
import org.redkale.net.WorkThread;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
@@ -28,6 +29,10 @@ public abstract class ClientRequest implements BiConsumer<ClientConnection, Byte
|
|||||||
|
|
||||||
ClientFuture respFuture;
|
ClientFuture respFuture;
|
||||||
|
|
||||||
|
public Serializable getRequestid() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public long getCreateTime() {
|
public long getCreateTime() {
|
||||||
return createTime;
|
return createTime;
|
||||||
}
|
}
|
||||||
@@ -45,7 +50,7 @@ public abstract class ClientRequest implements BiConsumer<ClientConnection, Byte
|
|||||||
return respFuture == null ? -1 : respFuture.mergeCount;
|
return respFuture == null ? -1 : respFuture.mergeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//是否能合并
|
//是否能合并, requestid=null的情况下值才有效
|
||||||
protected boolean canMerge(ClientConnection conn) {
|
protected boolean canMerge(ClientConnection conn) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.net.client;
|
package org.redkale.net.client;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
@@ -16,6 +18,10 @@ public class ClientResponse<P> {
|
|||||||
|
|
||||||
protected Throwable exc;
|
protected Throwable exc;
|
||||||
|
|
||||||
|
public Serializable getRequestid() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public ClientResponse(P result) {
|
public ClientResponse(P result) {
|
||||||
this.message = result;
|
this.message = result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user