Transport的pollConnection方法改成异步模式
This commit is contained in:
@@ -135,11 +135,34 @@ public abstract class AsyncConnection implements AsynchronousByteChannel, AutoCl
|
||||
*/
|
||||
public static CompletableFuture<AsyncConnection> createTCP(final AsynchronousChannelGroup group, final SocketAddress address,
|
||||
final int readTimeoutSecond0, final int writeTimeoutSecond0) throws IOException {
|
||||
return createTCP(group, address, false, readTimeoutSecond0, writeTimeoutSecond0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建TCP协议客户端连接
|
||||
*
|
||||
* @param address 连接点子
|
||||
* @param group 连接AsynchronousChannelGroup
|
||||
* @param noDelay TcpNoDelay
|
||||
* @param readTimeoutSecond0 读取超时秒数
|
||||
* @param writeTimeoutSecond0 写入超时秒数
|
||||
*
|
||||
* @return 连接CompletableFuture
|
||||
* @throws java.io.IOException 异常
|
||||
*/
|
||||
public static CompletableFuture<AsyncConnection> createTCP(final AsynchronousChannelGroup group, final SocketAddress address,
|
||||
final boolean noDelay, final int readTimeoutSecond0, final int writeTimeoutSecond0) throws IOException {
|
||||
final CompletableFuture future = new CompletableFuture();
|
||||
final AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(group);
|
||||
channel.connect(address, null, new CompletionHandler<Void, Void>() {
|
||||
@Override
|
||||
public void completed(Void result, Void attachment) {
|
||||
if (noDelay) {
|
||||
try {
|
||||
channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
future.complete(create(channel, address, readTimeoutSecond0, writeTimeoutSecond0));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.nio.channels.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import org.redkale.convert.*;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.util.*;
|
||||
@@ -188,7 +189,7 @@ public final class Transport {
|
||||
return tcp;
|
||||
}
|
||||
|
||||
public AsyncConnection pollConnection(SocketAddress addr) {
|
||||
public CompletableFuture<AsyncConnection> pollConnection(SocketAddress addr) {
|
||||
if (this.strategy != null) return strategy.pollConnection(addr, this);
|
||||
if (addr == null && this.transportAddres.length == 1) addr = this.transportAddres[0].address;
|
||||
final boolean rand = addr == null;
|
||||
@@ -207,7 +208,7 @@ public final class Transport {
|
||||
if (!queue.isEmpty()) {
|
||||
AsyncConnection conn;
|
||||
while ((conn = queue.poll()) != null) {
|
||||
if (conn.isOpen()) return conn;
|
||||
if (conn.isOpen()) return CompletableFuture.completedFuture(conn);
|
||||
}
|
||||
}
|
||||
tryed = true;
|
||||
@@ -247,14 +248,14 @@ public final class Transport {
|
||||
if (supportTcpNoDelay) channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
|
||||
channel.connect(addr).get(2, TimeUnit.SECONDS);
|
||||
}
|
||||
if (channel == null) return null;
|
||||
return AsyncConnection.create(channel, addr, 3000, 3000);
|
||||
if (channel == null) return CompletableFuture.completedFuture(null);
|
||||
return CompletableFuture.completedFuture(AsyncConnection.create(channel, addr, 3000, 3000));
|
||||
} else { // UDP
|
||||
if (rand) addr = this.transportAddres[0].address;
|
||||
DatagramChannel channel = DatagramChannel.open();
|
||||
channel.configureBlocking(true);
|
||||
channel.connect(addr);
|
||||
return AsyncConnection.create(channel, addr, true, 3000, 3000);
|
||||
return CompletableFuture.completedFuture(AsyncConnection.create(channel, addr, true, 3000, 3000));
|
||||
// AsyncDatagramChannel channel = AsyncDatagramChannel.open(group);
|
||||
// channel.connect(addr);
|
||||
// return AsyncConnection.create(channel, addr, true, 3000, 3000);
|
||||
@@ -280,7 +281,11 @@ public final class Transport {
|
||||
}
|
||||
|
||||
public <A> void async(SocketAddress addr, final ByteBuffer buffer, A att, final CompletionHandler<Integer, A> handler) {
|
||||
final AsyncConnection conn = pollConnection(addr);
|
||||
pollConnection(addr).whenComplete((conn, ex) -> {
|
||||
if (ex != null) {
|
||||
factory.getLogger().log(Level.WARNING, Transport.class.getSimpleName() + " async error", ex);
|
||||
return;
|
||||
}
|
||||
conn.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
|
||||
|
||||
@Override
|
||||
@@ -310,6 +315,7 @@ public final class Transport {
|
||||
offerConnection(true, conn);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static class TransportAddress {
|
||||
|
||||
@@ -248,6 +248,10 @@ public class TransportFactory {
|
||||
return new ArrayList<>(this.groupInfos.values());
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void addSncpService(Service service) {
|
||||
if (service == null) return;
|
||||
services.add(new WeakReference<>(service));
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.redkale.net;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 远程请求的负载均衡策略
|
||||
@@ -17,5 +18,5 @@ import java.net.SocketAddress;
|
||||
*/
|
||||
public interface TransportStrategy {
|
||||
|
||||
public AsyncConnection pollConnection(SocketAddress addr, Transport transport);
|
||||
public CompletableFuture<AsyncConnection> pollConnection(SocketAddress addr, Transport transport);
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ public final class SncpClient {
|
||||
final Type[] myparamtypes = action.paramTypes;
|
||||
final Class[] myparamclass = action.paramClass;
|
||||
if (action.addressSourceParamIndex >= 0) params[action.addressSourceParamIndex] = this.clientAddress;
|
||||
final BsonWriter writer = bsonConvert.pollBsonWriter(transport == null ? bufferSupplier : transport.getBufferSupplier()); // 将head写入
|
||||
final BsonWriter writer = bsonConvert.pollBsonWriter(transport.getBufferSupplier()); // 将head写入
|
||||
writer.writeTo(DEFAULT_HEADER);
|
||||
for (int i = 0; i < params.length; i++) { //params 可能包含: 3 个 boolean
|
||||
bsonConvert.convertTo(writer, AsyncHandler.class.isAssignableFrom(myparamclass[i]) ? AsyncHandler.class : myparamtypes[i], params[i]);
|
||||
@@ -351,14 +351,9 @@ public final class SncpClient {
|
||||
final long seqid = System.nanoTime();
|
||||
final DLong actionid = action.actionid;
|
||||
final SocketAddress addr = addr0 == null ? (action.addressTargetParamIndex >= 0 ? (SocketAddress) params[action.addressTargetParamIndex] : null) : addr0;
|
||||
CompletableFuture<AsyncConnection> connFuture = transport.pollConnection(addr);
|
||||
return connFuture.thenCompose(conn0 -> {
|
||||
final CompletableFuture<byte[]> future = new CompletableFuture();
|
||||
AsyncConnection conn0;
|
||||
try {
|
||||
conn0 = transport.pollConnection(addr);
|
||||
} catch (Exception e) {
|
||||
future.completeExceptionally(e);
|
||||
return future;
|
||||
}
|
||||
if (conn0 == null || !conn0.isOpen()) {
|
||||
future.completeExceptionally(new RuntimeException("sncp " + (conn0 == null ? addr : conn0.getRemoteAddress()) + " cannot connect"));
|
||||
return future;
|
||||
@@ -491,6 +486,7 @@ public final class SncpClient {
|
||||
}
|
||||
});
|
||||
return future;
|
||||
});
|
||||
}
|
||||
|
||||
private void checkResult(long seqid, final SncpAction action, ByteBuffer buffer) {
|
||||
|
||||
Reference in New Issue
Block a user