|
|
@ -55,7 +55,6 @@ import org.slf4j.LoggerFactory; |
|
|
|
import io.netty.bootstrap.Bootstrap; |
|
|
|
import io.netty.bootstrap.Bootstrap; |
|
|
|
import io.netty.channel.Channel; |
|
|
|
import io.netty.channel.Channel; |
|
|
|
import io.netty.channel.ChannelFuture; |
|
|
|
import io.netty.channel.ChannelFuture; |
|
|
|
import io.netty.channel.ChannelFutureListener; |
|
|
|
|
|
|
|
import io.netty.channel.ChannelInitializer; |
|
|
|
import io.netty.channel.ChannelInitializer; |
|
|
|
import io.netty.channel.ChannelOption; |
|
|
|
import io.netty.channel.ChannelOption; |
|
|
|
import io.netty.channel.EventLoopGroup; |
|
|
|
import io.netty.channel.EventLoopGroup; |
|
|
@ -84,7 +83,7 @@ public class NettyRemotingClient { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* channels |
|
|
|
* channels |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final ConcurrentHashMap<Host, Channel> channels = new ConcurrentHashMap(128); |
|
|
|
private final ConcurrentHashMap<Host, Channel> channels = new ConcurrentHashMap<>(128); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* started flag |
|
|
|
* started flag |
|
|
@ -130,7 +129,7 @@ public class NettyRemotingClient { |
|
|
|
this.clientConfig = clientConfig; |
|
|
|
this.clientConfig = clientConfig; |
|
|
|
if (NettyUtils.useEpoll()) { |
|
|
|
if (NettyUtils.useEpoll()) { |
|
|
|
this.workerGroup = new EpollEventLoopGroup(clientConfig.getWorkerThreads(), new ThreadFactory() { |
|
|
|
this.workerGroup = new EpollEventLoopGroup(clientConfig.getWorkerThreads(), new ThreadFactory() { |
|
|
|
private AtomicInteger threadIndex = new AtomicInteger(0); |
|
|
|
private final AtomicInteger threadIndex = new AtomicInteger(0); |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Thread newThread(Runnable r) { |
|
|
|
public Thread newThread(Runnable r) { |
|
|
@ -139,7 +138,7 @@ public class NettyRemotingClient { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
this.workerGroup = new NioEventLoopGroup(clientConfig.getWorkerThreads(), new ThreadFactory() { |
|
|
|
this.workerGroup = new NioEventLoopGroup(clientConfig.getWorkerThreads(), new ThreadFactory() { |
|
|
|
private AtomicInteger threadIndex = new AtomicInteger(0); |
|
|
|
private final AtomicInteger threadIndex = new AtomicInteger(0); |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Thread newThread(Runnable r) { |
|
|
|
public Thread newThread(Runnable r) { |
|
|
@ -178,13 +177,7 @@ public class NettyRemotingClient { |
|
|
|
.addLast(new NettyDecoder(), clientHandler, encoder); |
|
|
|
.addLast(new NettyDecoder(), clientHandler, encoder); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
this.responseFutureExecutor.scheduleAtFixedRate(new Runnable() { |
|
|
|
this.responseFutureExecutor.scheduleAtFixedRate(ResponseFuture::scanFutureTable, 5000, 1000, TimeUnit.MILLISECONDS); |
|
|
|
@Override |
|
|
|
|
|
|
|
public void run() { |
|
|
|
|
|
|
|
ResponseFuture.scanFutureTable(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, 5000, 1000, TimeUnit.MILLISECONDS); |
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
isStarted.compareAndSet(false, true); |
|
|
|
isStarted.compareAndSet(false, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -195,8 +188,6 @@ public class NettyRemotingClient { |
|
|
|
* @param command command |
|
|
|
* @param command command |
|
|
|
* @param timeoutMillis timeoutMillis |
|
|
|
* @param timeoutMillis timeoutMillis |
|
|
|
* @param invokeCallback callback function |
|
|
|
* @param invokeCallback callback function |
|
|
|
* @throws InterruptedException |
|
|
|
|
|
|
|
* @throws RemotingException |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void sendAsync(final Host host, final Command command, |
|
|
|
public void sendAsync(final Host host, final Command command, |
|
|
|
final long timeoutMillis, |
|
|
|
final long timeoutMillis, |
|
|
@ -205,18 +196,18 @@ public class NettyRemotingClient { |
|
|
|
if (channel == null) { |
|
|
|
if (channel == null) { |
|
|
|
throw new RemotingException("network error"); |
|
|
|
throw new RemotingException("network error"); |
|
|
|
} |
|
|
|
} |
|
|
|
/** |
|
|
|
/* |
|
|
|
* request unique identification |
|
|
|
* request unique identification |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
final long opaque = command.getOpaque(); |
|
|
|
final long opaque = command.getOpaque(); |
|
|
|
/** |
|
|
|
/* |
|
|
|
* control concurrency number |
|
|
|
* control concurrency number |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
boolean acquired = this.asyncSemaphore.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS); |
|
|
|
boolean acquired = this.asyncSemaphore.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS); |
|
|
|
if (acquired) { |
|
|
|
if (acquired) { |
|
|
|
final ReleaseSemaphore releaseSemaphore = new ReleaseSemaphore(this.asyncSemaphore); |
|
|
|
final ReleaseSemaphore releaseSemaphore = new ReleaseSemaphore(this.asyncSemaphore); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/* |
|
|
|
* response future |
|
|
|
* response future |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
final ResponseFuture responseFuture = new ResponseFuture(opaque, |
|
|
|
final ResponseFuture responseFuture = new ResponseFuture(opaque, |
|
|
@ -224,10 +215,7 @@ public class NettyRemotingClient { |
|
|
|
invokeCallback, |
|
|
|
invokeCallback, |
|
|
|
releaseSemaphore); |
|
|
|
releaseSemaphore); |
|
|
|
try { |
|
|
|
try { |
|
|
|
channel.writeAndFlush(command).addListener(new ChannelFutureListener() { |
|
|
|
channel.writeAndFlush(command).addListener(future -> { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void operationComplete(ChannelFuture future) throws Exception { |
|
|
|
|
|
|
|
if (future.isSuccess()) { |
|
|
|
if (future.isSuccess()) { |
|
|
|
responseFuture.setSendOk(true); |
|
|
|
responseFuture.setSendOk(true); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -238,14 +226,13 @@ public class NettyRemotingClient { |
|
|
|
responseFuture.putResponse(null); |
|
|
|
responseFuture.putResponse(null); |
|
|
|
try { |
|
|
|
try { |
|
|
|
responseFuture.executeInvokeCallback(); |
|
|
|
responseFuture.executeInvokeCallback(); |
|
|
|
} catch (Throwable ex) { |
|
|
|
} catch (Exception ex) { |
|
|
|
logger.error("execute callback error", ex); |
|
|
|
logger.error("execute callback error", ex); |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
responseFuture.release(); |
|
|
|
responseFuture.release(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} catch (Throwable ex) { |
|
|
|
} catch (Exception ex) { |
|
|
|
responseFuture.release(); |
|
|
|
responseFuture.release(); |
|
|
|
throw new RemotingException(String.format("send command to host: %s failed", host), ex); |
|
|
|
throw new RemotingException(String.format("send command to host: %s failed", host), ex); |
|
|
|
} |
|
|
|
} |
|
|
@ -263,8 +250,6 @@ public class NettyRemotingClient { |
|
|
|
* @param command command |
|
|
|
* @param command command |
|
|
|
* @param timeoutMillis timeoutMillis |
|
|
|
* @param timeoutMillis timeoutMillis |
|
|
|
* @return command |
|
|
|
* @return command |
|
|
|
* @throws InterruptedException |
|
|
|
|
|
|
|
* @throws RemotingException |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Command sendSync(final Host host, final Command command, final long timeoutMillis) throws InterruptedException, RemotingException { |
|
|
|
public Command sendSync(final Host host, final Command command, final long timeoutMillis) throws InterruptedException, RemotingException { |
|
|
|
final Channel channel = getChannel(host); |
|
|
|
final Channel channel = getChannel(host); |
|
|
@ -273,9 +258,7 @@ public class NettyRemotingClient { |
|
|
|
} |
|
|
|
} |
|
|
|
final long opaque = command.getOpaque(); |
|
|
|
final long opaque = command.getOpaque(); |
|
|
|
final ResponseFuture responseFuture = new ResponseFuture(opaque, timeoutMillis, null, null); |
|
|
|
final ResponseFuture responseFuture = new ResponseFuture(opaque, timeoutMillis, null, null); |
|
|
|
channel.writeAndFlush(command).addListener(new ChannelFutureListener() { |
|
|
|
channel.writeAndFlush(command).addListener(future -> { |
|
|
|
@Override |
|
|
|
|
|
|
|
public void operationComplete(ChannelFuture future) throws Exception { |
|
|
|
|
|
|
|
if (future.isSuccess()) { |
|
|
|
if (future.isSuccess()) { |
|
|
|
responseFuture.setSendOk(true); |
|
|
|
responseFuture.setSendOk(true); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -285,9 +268,8 @@ public class NettyRemotingClient { |
|
|
|
responseFuture.setCause(future.cause()); |
|
|
|
responseFuture.setCause(future.cause()); |
|
|
|
responseFuture.putResponse(null); |
|
|
|
responseFuture.putResponse(null); |
|
|
|
logger.error("send command {} to host {} failed", command, host); |
|
|
|
logger.error("send command {} to host {} failed", command, host); |
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
/** |
|
|
|
/* |
|
|
|
* sync wait for result |
|
|
|
* sync wait for result |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Command result = responseFuture.waitResponse(); |
|
|
|
Command result = responseFuture.waitResponse(); |
|
|
@ -306,7 +288,6 @@ public class NettyRemotingClient { |
|
|
|
* |
|
|
|
* |
|
|
|
* @param host host |
|
|
|
* @param host host |
|
|
|
* @param command command |
|
|
|
* @param command command |
|
|
|
* @throws RemotingException |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void send(final Host host, final Command command) throws RemotingException { |
|
|
|
public void send(final Host host, final Command command) throws RemotingException { |
|
|
|
Channel channel = getChannel(host); |
|
|
|
Channel channel = getChannel(host); |
|
|
@ -351,9 +332,6 @@ public class NettyRemotingClient { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* get channel |
|
|
|
* get channel |
|
|
|
* |
|
|
|
|
|
|
|
* @param host |
|
|
|
|
|
|
|
* @return |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Channel getChannel(Host host) { |
|
|
|
public Channel getChannel(Host host) { |
|
|
|
Channel channel = channels.get(host); |
|
|
|
Channel channel = channels.get(host); |
|
|
|