encode bugfix (#4548)

* basic spell fix.import
 fail bugfix

* encode bugfix

* remote log bugfix;  create client concurrent bugfix;optimize log

* checkstyle  fix

* checkstyle  fix

* checkstyle  fix

* checkstyle  fix

* checkstyle  fix

* checkstyle pmd fix

* checkstyle pmd fix

* http poll sla bugfix; rpc config listen notify optimize
This commit is contained in:
nov.lzf 2020-12-26 15:53:10 +08:00 committed by GitHub
parent f486561bc9
commit 6e34f2886b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 577 additions and 501 deletions

View File

@ -93,7 +93,7 @@ public interface CmdbService {
* *
* @param entityName name of entity * @param entityName name of entity
* @param entityType type of entity * @param entityType type of entity
* @return * @return entity.
*/ */
Entity getEntity(String entityName, String entityType); Entity getEntity(String entityName, String entityType);
} }

View File

@ -41,7 +41,7 @@ public class ConfigChangeClusterSyncRequest extends AbstractConfigRequest {
/** /**
* is beta. * is beta.
* *
* @return * @return is beta or not.
*/ */
public boolean isBeta() { public boolean isBeta() {
return "Y".equalsIgnoreCase(isBeta); return "Y".equalsIgnoreCase(isBeta);

View File

@ -37,6 +37,7 @@ public class ConfigChangeBatchListenResponse extends Response {
/** /**
* add changed config. * add changed config.
*
* @param dataId dataId. * @param dataId dataId.
* @param group group. * @param group group.
* @param tenant tenant. * @param tenant tenant.
@ -71,7 +72,7 @@ public class ConfigChangeBatchListenResponse extends Response {
* build fail response. * build fail response.
* *
* @param errorMessage errorMessage. * @param errorMessage errorMessage.
* @return * @return response.
*/ */
public static ConfigChangeBatchListenResponse buildFailResponse(String errorMessage) { public static ConfigChangeBatchListenResponse buildFailResponse(String errorMessage) {
ConfigChangeBatchListenResponse response = new ConfigChangeBatchListenResponse(); ConfigChangeBatchListenResponse response = new ConfigChangeBatchListenResponse();

View File

@ -20,35 +20,35 @@ import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.api.remote.response.ResponseCode; import com.alibaba.nacos.api.remote.response.ResponseCode;
/** /**
* ConfigPubishResponse. * ConfigPublishResponse.
* *
* @author liuzunfei * @author liuzunfei
* @version $Id: ConfigPubishResponse.java, v 0.1 2020年07月16日 4:59 PM liuzunfei Exp $ * @version $Id: ConfigPubishResponse.java, v 0.1 2020年07月16日 4:59 PM liuzunfei Exp $
*/ */
public class ConfigPubishResponse extends Response { public class ConfigPublishResponse extends Response {
public ConfigPubishResponse() { public ConfigPublishResponse() {
super(); super();
} }
/** /**
* Buidl success resposne. * Build success response.
* *
* @return * @return response.
*/ */
public static ConfigPubishResponse buildSuccessResponse() { public static ConfigPublishResponse buildSuccessResponse() {
return new ConfigPubishResponse(); return new ConfigPublishResponse();
} }
/** /**
* Buidl fail resposne. * Build fail response.
* *
* @return * @return response.
*/ */
public static ConfigPubishResponse buildFailResponse(String errorMsg) { public static ConfigPublishResponse buildFailResponse(String errorMsg) {
ConfigPubishResponse configPubishResponse = new ConfigPubishResponse(); ConfigPublishResponse configPublishResponse = new ConfigPublishResponse();
configPubishResponse.setResultCode(ResponseCode.FAIL.getCode()); configPublishResponse.setResultCode(ResponseCode.FAIL.getCode());
configPubishResponse.setMessage(errorMsg); configPublishResponse.setMessage(errorMsg);
return configPubishResponse; return configPublishResponse;
} }
} }

View File

@ -57,7 +57,7 @@ public class ConfigQueryResponse extends Response {
* *
* @param errorCode errorCode. * @param errorCode errorCode.
* @param message message. * @param message message.
* @return * @return response.
*/ */
public static ConfigQueryResponse buildFailResponse(int errorCode, String message) { public static ConfigQueryResponse buildFailResponse(int errorCode, String message) {
ConfigQueryResponse response = new ConfigQueryResponse(); ConfigQueryResponse response = new ConfigQueryResponse();
@ -66,10 +66,10 @@ public class ConfigQueryResponse extends Response {
} }
/** /**
* Buidl success resposne. * Build success response.
* *
* @param content content. * @param content content.
* @return * @return response.
*/ */
public static ConfigQueryResponse buildSuccessResponse(String content) { public static ConfigQueryResponse buildSuccessResponse(String content) {
ConfigQueryResponse response = new ConfigQueryResponse(); ConfigQueryResponse response = new ConfigQueryResponse();

View File

@ -32,18 +32,18 @@ public class ConfigRemoveResponse extends Response {
} }
/** /**
* Buidl success resposne. * Build success response.
* *
* @return * @return response.
*/ */
public static ConfigRemoveResponse buildSuccessResponse() { public static ConfigRemoveResponse buildSuccessResponse() {
return new ConfigRemoveResponse(); return new ConfigRemoveResponse();
} }
/** /**
* Buidl fail resposne. * Build fail response.
* *
* @return * @return response.
*/ */
public static ConfigRemoveResponse buildFailResponse(String errorMsg) { public static ConfigRemoveResponse buildFailResponse(String errorMsg) {
ConfigRemoveResponse removeResponse = new ConfigRemoveResponse(); ConfigRemoveResponse removeResponse = new ConfigRemoveResponse();

View File

@ -107,6 +107,11 @@ public class NacosException extends Exception {
*/ */
public static final int CLIENT_INVALID_PARAM = -400; public static final int CLIENT_INVALID_PARAM = -400;
/**
* invalid param参数错误.
*/
public static final int CLIENT_DISCONNECT = -401;
/** /**
* over client threshold超过server端的限流阈值. * over client threshold超过server端的限流阈值.
*/ */
@ -160,4 +165,6 @@ public class NacosException extends Exception {
* ome exceptions that occurred when the use the Nacos RestTemplate and Nacos AsyncRestTemplate. * ome exceptions that occurred when the use the Nacos RestTemplate and Nacos AsyncRestTemplate.
*/ */
public static final int HTTP_CLIENT_ERROR_CODE = -500; public static final int HTTP_CLIENT_ERROR_CODE = -500;
} }

View File

@ -82,7 +82,7 @@ public class DefaultRequestFuture implements RequestFuture {
this.requestId = requestId; this.requestId = requestId;
this.connectionId = connectionId; this.connectionId = connectionId;
if (requestCallBack != null) { if (requestCallBack != null) {
this.timeoutFuture = RpcScheduledExecutor.TIMEOUT_SHEDULER this.timeoutFuture = RpcScheduledExecutor.TIMEOUT_SCHEDULER
.schedule(new TimeoutHandler(), requestCallBack.getTimeout(), TimeUnit.MILLISECONDS); .schedule(new TimeoutHandler(), requestCallBack.getTimeout(), TimeUnit.MILLISECONDS);
} }
this.timeoutInnerTrigger = timeoutInnerTrigger; this.timeoutInnerTrigger = timeoutInnerTrigger;

View File

@ -31,14 +31,14 @@ public interface RequestCallBack<T extends Response> {
/** /**
* get executor on callback. * get executor on callback.
* *
* @return * @return executor.
*/ */
public Executor getExecutor(); public Executor getExecutor();
/** /**
* get timeout mills. * get timeout mills.
* *
* @return * @return timeouts.
*/ */
public long getTimeout(); public long getTimeout();

View File

@ -31,7 +31,7 @@ public interface RequestFuture {
/** /**
* check that it is done or not.. * check that it is done or not..
* @return * @return is done .
*/ */
boolean isDone(); boolean isDone();

View File

@ -87,7 +87,7 @@ public interface Requester {
/** /**
* check this requester is busy. * check this requester is busy.
* *
* @return * @return busy or not.
*/ */
public boolean isBusy(); public boolean isBusy();
} }

View File

@ -27,17 +27,11 @@ import java.util.concurrent.ThreadFactory;
*/ */
public class RpcScheduledExecutor extends ScheduledThreadPoolExecutor { public class RpcScheduledExecutor extends ScheduledThreadPoolExecutor {
public static final RpcScheduledExecutor TIMEOUT_SHEDULER = new RpcScheduledExecutor(1, public static final RpcScheduledExecutor TIMEOUT_SCHEDULER = new RpcScheduledExecutor(0,
"com.alibaba.nacos.remote.TimerScheduler"); "com.alibaba.nacos.remote.TimerScheduler");
/**
* executor to execute future request.
*/
public static final RpcScheduledExecutor AYNS_REQUEST_EXECUTOR = new RpcScheduledExecutor(
Runtime.getRuntime().availableProcessors(), "com.alibaba.nacos.remote.RpcRequestExecutor");
public static final RpcScheduledExecutor COMMON_SERVER_EXECUTOR = new RpcScheduledExecutor( public static final RpcScheduledExecutor COMMON_SERVER_EXECUTOR = new RpcScheduledExecutor(
Runtime.getRuntime().availableProcessors(), "com.alibaba.nacos.remote.ServerCommonScheduler"); 0, "com.alibaba.nacos.remote.ServerCommonScheduler");
public RpcScheduledExecutor(int corePoolSize, final String threadName) { public RpcScheduledExecutor(int corePoolSize, final String threadName) {
super(corePoolSize, new ThreadFactory() { super(corePoolSize, new ThreadFactory() {

View File

@ -115,6 +115,6 @@ public abstract class Request {
@Override @Override
public String toString() { public String toString() {
return "Request{" + "headers=" + headers + ", requestId='" + requestId + '\'' + '}'; return this.getClass().getSimpleName() + "{" + "headers=" + headers + ", requestId='" + requestId + '\'' + '}';
} }
} }

View File

@ -52,9 +52,9 @@ public abstract class Response {
} }
/** /**
* Check Response is Successd. * Check Response is Successed.
* *
* @return * @return success or not.
*/ */
public boolean isSuccess() { public boolean isSuccess() {
return this.resultCode == ResponseCode.SUCCESS.getCode(); return this.resultCode == ResponseCode.SUCCESS.getCode();

View File

@ -51,14 +51,6 @@ public class CacheData {
this.isInitializing = isInitializing; this.isInitializing = isInitializing;
} }
public boolean isListenSuccess() {
return isListenSuccess;
}
public void setListenSuccess(boolean listenSuccess) {
isListenSuccess = listenSuccess;
}
public String getMd5() { public String getMd5() {
return md5; return md5;
} }
@ -285,6 +277,21 @@ public class CacheData {
return content; return content;
} }
/**
* 1.first add listener.default is false;need to check.
* 2.receive config change notify,set false;need to check.
* 3.last listener is remove,set to false;need to check
*
* @return
*/
public boolean isSync() {
return isSync;
}
public void setSync(boolean sync) {
isSync = sync;
}
public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) { public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) {
if (null == dataId || null == group) { if (null == dataId || null == group) {
throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group); throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
@ -350,7 +357,10 @@ public class CacheData {
private volatile boolean isInitializing = true; private volatile boolean isInitializing = true;
private volatile boolean isListenSuccess = false; /**
* if is sync with the server.
*/
private volatile boolean isSync = false;
private String type; private String type;

View File

@ -27,13 +27,12 @@ import com.alibaba.nacos.api.config.remote.request.ConfigQueryRequest;
import com.alibaba.nacos.api.config.remote.request.ConfigRemoveRequest; import com.alibaba.nacos.api.config.remote.request.ConfigRemoveRequest;
import com.alibaba.nacos.api.config.remote.response.ConfigChangeBatchListenResponse; import com.alibaba.nacos.api.config.remote.response.ConfigChangeBatchListenResponse;
import com.alibaba.nacos.api.config.remote.response.ConfigChangeNotifyResponse; import com.alibaba.nacos.api.config.remote.response.ConfigChangeNotifyResponse;
import com.alibaba.nacos.api.config.remote.response.ConfigPubishResponse; import com.alibaba.nacos.api.config.remote.response.ConfigPublishResponse;
import com.alibaba.nacos.api.config.remote.response.ConfigQueryResponse; import com.alibaba.nacos.api.config.remote.response.ConfigQueryResponse;
import com.alibaba.nacos.api.config.remote.response.ConfigRemoveResponse; import com.alibaba.nacos.api.config.remote.response.ConfigRemoveResponse;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.remote.RemoteConstants; import com.alibaba.nacos.api.remote.RemoteConstants;
import com.alibaba.nacos.api.remote.request.Request; import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.api.remote.response.Response; import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.client.config.common.GroupKey; import com.alibaba.nacos.client.config.common.GroupKey;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
@ -58,7 +57,6 @@ import com.alibaba.nacos.common.remote.client.ConnectionEventListener;
import com.alibaba.nacos.common.remote.client.RpcClient; import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory; import com.alibaba.nacos.common.remote.client.RpcClientFactory;
import com.alibaba.nacos.common.remote.client.ServerListFactory; import com.alibaba.nacos.common.remote.client.ServerListFactory;
import com.alibaba.nacos.common.remote.client.ServerRequestHandler;
import com.alibaba.nacos.common.utils.ConvertUtils; import com.alibaba.nacos.common.utils.ConvertUtils;
import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.StringUtils;
@ -116,29 +114,11 @@ public class ClientWorker implements Closeable {
for (Listener listener : listeners) { for (Listener listener : listeners) {
cache.addListener(listener); cache.addListener(listener);
} }
if (!cache.isListenSuccess()) { if (!cache.isSync()) {
agent.notifyListenConfig(); agent.notifyListenConfig();
} }
} }
/**
* Remove listener.
*
* @param dataId dataId of data
* @param group group of data
* @param listener listener
*/
public void removeListener(String dataId, String group, Listener listener) {
group = null2defaultGroup(group);
CacheData cache = getCache(dataId, group);
if (null != cache) {
cache.removeListener(listener);
if (cache.getListeners().isEmpty()) {
agent.removeCache(dataId, group);
}
}
}
/** /**
* Add listeners for tenant. * Add listeners for tenant.
* *
@ -152,14 +132,17 @@ public class ClientWorker implements Closeable {
group = null2defaultGroup(group); group = null2defaultGroup(group);
String tenant = agent.getTenant(); String tenant = agent.getTenant();
CacheData cache = addCacheDataIfAbsent(dataId, group, tenant); CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
synchronized (cache) {
for (Listener listener : listeners) { for (Listener listener : listeners) {
cache.addListener(listener); cache.addListener(listener);
} }
if (!cache.isListenSuccess()) { if (!cache.isSync()) {
agent.notifyListenConfig(); agent.notifyListenConfig();
} }
} }
}
/** /**
* Add listeners for tenant with content. * Add listeners for tenant with content.
* *
@ -174,16 +157,41 @@ public class ClientWorker implements Closeable {
group = null2defaultGroup(group); group = null2defaultGroup(group);
String tenant = agent.getTenant(); String tenant = agent.getTenant();
CacheData cache = addCacheDataIfAbsent(dataId, group, tenant); CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
synchronized (cache) {
cache.setContent(content); cache.setContent(content);
for (Listener listener : listeners) { for (Listener listener : listeners) {
cache.addListener(listener); cache.addListener(listener);
} }
// if current cache is already at listening status,do not notify. // if current cache is already at listening status,do not notify.
if (!cache.isListenSuccess()) { if (!cache.isSync()) {
agent.notifyListenConfig(); agent.notifyListenConfig();
} }
} }
}
/**
* Remove listener.
*
* @param dataId dataId of data
* @param group group of data
* @param listener listener
*/
public void removeListener(String dataId, String group, Listener listener) {
group = null2defaultGroup(group);
CacheData cache = getCache(dataId, group);
if (null != cache) {
synchronized (cache) {
cache.removeListener(listener);
if (cache.getListeners().isEmpty()) {
cache.setSync(false);
agent.removeCache(dataId, group);
}
}
}
}
/** /**
* Remove listeners for tenant. * Remove listeners for tenant.
* *
@ -198,6 +206,7 @@ public class ClientWorker implements Closeable {
if (null != cache) { if (null != cache) {
cache.removeListener(listener); cache.removeListener(listener);
if (cache.getListeners().isEmpty()) { if (cache.getListeners().isEmpty()) {
cache.setSync(false);
agent.removeCache(dataId, group); agent.removeCache(dataId, group);
} }
} }
@ -425,22 +434,12 @@ public class ClientWorker implements Closeable {
agent = new ConfigRpcTransportClient(properties, serverListManager); agent = new ConfigRpcTransportClient(properties, serverListManager);
} }
this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory() { ScheduledExecutorService executorService = Executors
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
t.setDaemon(true);
return t;
}
});
this.executorService = Executors
.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() { .newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r); Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName()); t.setName("com.alibaba.nacos.client.Worker_" + agent.getName());
t.setDaemon(true); t.setDaemon(true);
return t; return t;
} }
@ -464,6 +463,11 @@ public class ClientWorker implements Closeable {
if (null != ct[1]) { if (null != ct[1]) {
cacheData.setType(ct[1]); cacheData.setType(ct[1]);
} }
if (notify) {
LOGGER.info("[{}] [data-received] dataId={}, group={}, tenant={}, md5={}, content={}, type={}",
agent.getName(), cacheData.dataId, cacheData.group, cacheData.tenant, cacheData.getMd5(),
ContentUtils.truncateContent(ct[0]), ct[1]);
}
cacheData.checkListenerMd5(); cacheData.checkListenerMd5();
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("refresh content and check md5 fail ,dataid={},group={},tenant={} ", cacheData.dataId, LOGGER.error("refresh content and check md5 fail ,dataid={},group={},tenant={} ", cacheData.dataId,
@ -487,8 +491,7 @@ public class ClientWorker implements Closeable {
public void shutdown() throws NacosException { public void shutdown() throws NacosException {
String className = this.getClass().getName(); String className = this.getClass().getName();
LOGGER.info("{} do shutdown begin", className); LOGGER.info("{} do shutdown begin", className);
ThreadUtils.shutdownThreadPool(executorService, LOGGER); ThreadUtils.shutdownThreadPool(agent.executor, LOGGER);
ThreadUtils.shutdownThreadPool(executor, LOGGER);
LOGGER.info("{} do shutdown stop", className); LOGGER.info("{} do shutdown stop", className);
} }
@ -500,10 +503,6 @@ public class ClientWorker implements Closeable {
this.isHealthServer = isHealthServer; this.isHealthServer = isHealthServer;
} }
final ScheduledExecutorService executor;
final ScheduledExecutorService executorService;
/** /**
* groupKey -> cacheData. * groupKey -> cacheData.
*/ */
@ -536,13 +535,13 @@ public class ClientWorker implements Closeable {
super(properties, serverListManager); super(properties, serverListManager);
} }
private ConnectionType getConectiontype() { private ConnectionType getConnectionType() {
ConnectionType connectionType = ConnectionType.GRPC; ConnectionType connectionType = ConnectionType.GRPC;
String connetionType = ParamUtils.configRemoteConnectionType(); String connectionTypeString = ParamUtils.configRemoteConnectionType();
if (StringUtils.isNotBlank(connetionType)) { if (StringUtils.isNotBlank(connectionTypeString)) {
ConnectionType connectionType1 = ConnectionType.valueOf(connetionType); ConnectionType connectionTypeInner = ConnectionType.valueOf(connectionTypeString);
if (connectionType1 != null) { if (connectionTypeInner != null) {
connectionType = connectionType1; connectionType = connectionTypeInner;
} }
} }
return connectionType; return connectionType;
@ -560,13 +559,15 @@ public class ClientWorker implements Closeable {
/* /*
* Register Listen Change Handler * Register Listen Change Handler
*/ */
rpcClientInner.registerServerPushResponseHandler(new ServerRequestHandler() { rpcClientInner.registerServerPushResponseHandler((request, requestMeta) -> {
@Override
public Response requestReply(Request request, RequestMeta requestMeta) {
if (request instanceof ConfigChangeNotifyRequest) { if (request instanceof ConfigChangeNotifyRequest) {
ConfigChangeNotifyRequest configChangeNotifyRequest = (ConfigChangeNotifyRequest) request; ConfigChangeNotifyRequest configChangeNotifyRequest = (ConfigChangeNotifyRequest) request;
String groupKey = GroupKey.getKeyTenant(configChangeNotifyRequest.getDataId(), LOGGER.info("[{}] [server-push] config changed. dataId={}, group={}", getName(),
configChangeNotifyRequest.getGroup(), configChangeNotifyRequest.getTenant()); configChangeNotifyRequest.getDataId(), configChangeNotifyRequest.getGroup());
String groupKey = GroupKey
.getKeyTenant(configChangeNotifyRequest.getDataId(), configChangeNotifyRequest.getGroup(),
configChangeNotifyRequest.getTenant());
CacheData cacheData = cacheMap.get().get(groupKey); CacheData cacheData = cacheMap.get().get(groupKey);
if (cacheData != null) { if (cacheData != null) {
if (configChangeNotifyRequest.isContentPush() if (configChangeNotifyRequest.isContentPush()
@ -575,35 +576,34 @@ public class ClientWorker implements Closeable {
cacheData.setType(configChangeNotifyRequest.getType()); cacheData.setType(configChangeNotifyRequest.getType());
cacheData.checkListenerMd5(); cacheData.checkListenerMd5();
} }
cacheData.setListenSuccess(false); cacheData.setSync(false);
notifyListenConfig(); notifyListenConfig();
} }
return new ConfigChangeNotifyResponse(); return new ConfigChangeNotifyResponse();
} }
return null; return null;
}
}); });
rpcClientInner.registerConnectionListener(new ConnectionEventListener() { rpcClientInner.registerConnectionListener(new ConnectionEventListener() {
@Override @Override
public void onConnected() { public void onConnected() {
LOGGER.info("[{}] Connected,notify listen context...", rpcClientInner.getName());
notifyListenConfig(); notifyListenConfig();
} }
@Override @Override
public void onDisConnect() { public void onDisConnect() {
String taskId = rpcClientInner.getLabels().get("taskId"); String taskId = rpcClientInner.getLabels().get("taskId");
LOGGER.info("[{}] clear listen context...", rpcClientInner.getName()); LOGGER.info("[{}] DisConnected,clear listen context...", rpcClientInner.getName());
Collection<CacheData> values = cacheMap.get().values(); Collection<CacheData> values = cacheMap.get().values();
for (CacheData cacheData : values) { for (CacheData cacheData : values) {
if (taskId != null && Integer.valueOf(taskId).equals(cacheData.getTaskId())) { if (taskId != null && Integer.valueOf(taskId).equals(cacheData.getTaskId())) {
cacheData.setListenSuccess(false); cacheData.setSync(false);
continue; continue;
} }
cacheData.setListenSuccess(false); cacheData.setSync(false);
} }
} }
@ -631,11 +631,10 @@ public class ClientWorker implements Closeable {
} }
@Override @Override
public void startIntenal() throws NacosException { public void startInternal() throws NacosException {
executor.schedule(new Runnable() { executor.schedule(new Runnable() {
@Override @Override
public void run() { public void run() {
try {
while (true) { while (true) {
try { try {
listenExecutebell.poll(5L, TimeUnit.SECONDS); listenExecutebell.poll(5L, TimeUnit.SECONDS);
@ -644,9 +643,6 @@ public class ClientWorker implements Closeable {
LOGGER.error("[ rpc listen execute ] [rpc listen] exception", e); LOGGER.error("[ rpc listen execute ] [rpc listen] exception", e);
} }
} }
} catch (Throwable e) {
LOGGER.error("rpc listen task exception", e);
}
} }
}, 0L, TimeUnit.MILLISECONDS); }, 0L, TimeUnit.MILLISECONDS);
@ -697,8 +693,11 @@ public class ClientWorker implements Closeable {
Map<String, List<CacheData>> removeListenCachesMap = new HashMap<String, List<CacheData>>(16); Map<String, List<CacheData>> removeListenCachesMap = new HashMap<String, List<CacheData>>(16);
for (CacheData cache : cacheMap.get().values()) { for (CacheData cache : cacheMap.get().values()) {
//get listen config and remove listen config if (cache.isSync()) {
if (!CollectionUtils.isEmpty(cache.getListeners()) && !cache.isListenSuccess()) { continue;
}
if (!CollectionUtils.isEmpty(cache.getListeners())) {
//get listen config
if (!cache.isUseLocalConfigInfo()) { if (!cache.isUseLocalConfigInfo()) {
List<CacheData> cacheDatas = listenCachesMap.get(String.valueOf(cache.getTaskId())); List<CacheData> cacheDatas = listenCachesMap.get(String.valueOf(cache.getTaskId()));
if (cacheDatas == null) { if (cacheDatas == null) {
@ -708,7 +707,7 @@ public class ClientWorker implements Closeable {
cacheDatas.add(cache); cacheDatas.add(cache);
} }
} else if (CollectionUtils.isEmpty(cache.getListeners()) && cache.isListenSuccess()) { } else if (CollectionUtils.isEmpty(cache.getListeners())) {
if (!cache.isUseLocalConfigInfo()) { if (!cache.isUseLocalConfigInfo()) {
List<CacheData> cacheDatas = removeListenCachesMap.get(String.valueOf(cache.getTaskId())); List<CacheData> cacheDatas = removeListenCachesMap.get(String.valueOf(cache.getTaskId()));
@ -731,7 +730,6 @@ public class ClientWorker implements Closeable {
configChangeListenRequest.setListen(true); configChangeListenRequest.setListen(true);
try { try {
RpcClient rpcClient = ensureRpcClient(taskId); RpcClient rpcClient = ensureRpcClient(taskId);
ConfigChangeBatchListenResponse configChangeBatchListenResponse = (ConfigChangeBatchListenResponse) requestProxy( ConfigChangeBatchListenResponse configChangeBatchListenResponse = (ConfigChangeBatchListenResponse) requestProxy(
rpcClient, configChangeListenRequest); rpcClient, configChangeListenRequest);
if (configChangeBatchListenResponse != null && configChangeBatchListenResponse.isSuccess()) { if (configChangeBatchListenResponse != null && configChangeBatchListenResponse.isSuccess()) {
@ -745,22 +743,38 @@ public class ClientWorker implements Closeable {
.getKeyTenant(changeConfig.getDataId(), changeConfig.getGroup(), .getKeyTenant(changeConfig.getDataId(), changeConfig.getGroup(),
changeConfig.getTenant()); changeConfig.getTenant());
changeKeys.add(changeKey); changeKeys.add(changeKey);
refreshContentAndCheck(changeKey, true); boolean isInitializing = cacheMap.get().get(changeKey).isInitializing();
this.executor.execute(() -> refreshContentAndCheck(changeKey, !isInitializing));
} }
} }
//handler constent configs //handler content configs
for (CacheData cacheData : listenCaches) { for (CacheData cacheData : listenCaches) {
if (!changeKeys.contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, if (!changeKeys.contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group,
cacheData.getTenant()))) { cacheData.getTenant()))) {
cacheData.setListenSuccess(true); //sync:cache data md5 = server md5 && cache data md5 = all listeners md5.
cacheData.checkListenerMd5();
cacheData.setSync(true);
} }
cacheData.setInitializing(false);
} }
} }
} catch (Exception e) { } catch (Exception e) {
if (e instanceof NacosException
&& ((NacosException) e).getErrCode() == NacosException.CLIENT_DISCONNECT) {
LOGGER.warn("async listen config change fail ,client is not connected.");
} else {
LOGGER.error("async listen config change error ", e); LOGGER.error("async listen config change error ", e);
} }
try {
Thread.sleep(10L);
} catch (InterruptedException interruptedException) {
//ignore
}
}
} }
} }
@ -775,24 +789,34 @@ public class ClientWorker implements Closeable {
boolean removeSuccess = unListenConfigChange(rpcClient, configChangeListenRequest); boolean removeSuccess = unListenConfigChange(rpcClient, configChangeListenRequest);
if (removeSuccess) { if (removeSuccess) {
for (CacheData cacheData : removeListenCaches) { for (CacheData cacheData : removeListenCaches) {
ClientWorker.this.removeCache(cacheData.dataId, cacheData.group, cacheData.tenant); synchronized (cacheData) {
if (cacheData.getListeners().isEmpty()) {
ClientWorker.this
.removeCache(cacheData.dataId, cacheData.group, cacheData.tenant);
}
}
} }
} }
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("async remove listen config change error ", e); LOGGER.error("async remove listen config change error ", e);
} }
try {
Thread.sleep(10L);
} catch (InterruptedException interruptedException) {
//ignore
}
} }
} }
} }
private RpcClient ensureRpcClient(String taskId) throws NacosException { private synchronized RpcClient ensureRpcClient(String taskId) throws NacosException {
Map<String, String> labels = getLabels(); Map<String, String> labels = getLabels();
Map<String, String> newlabels = new HashMap<String, String>(labels); Map<String, String> newlabels = new HashMap<String, String>(labels);
newlabels.put("taskId", taskId); newlabels.put("taskId", taskId);
RpcClient rpcClient = RpcClientFactory RpcClient rpcClient = RpcClientFactory
.createClient("config-" + taskId + "-" + uuid, getConectiontype(), newlabels); .createClient("config-" + taskId + "-" + uuid, getConnectionType(), newlabels);
if (rpcClient.isWaitInitiated()) { if (rpcClient.isWaitInitiated()) {
initHandlerRpcClient(rpcClient); initHandlerRpcClient(rpcClient);
rpcClient.start(); rpcClient.start();
@ -801,70 +825,11 @@ public class ClientWorker implements Closeable {
return rpcClient; return rpcClient;
} }
/**
* build config strings.
*
* @param caches caches to build config string.
* @return
*/
private List<String> buildConfigStrs(List<CacheData> caches) {
StringBuilder listenConfigsBuilder = new StringBuilder();
List<String> configStrings = new ArrayList<String>();
int index = 0;
for (CacheData cache : caches) {
index++;
listenConfigsBuilder.append(cache.dataId).append(WORD_SEPARATOR);
listenConfigsBuilder.append(cache.group).append(WORD_SEPARATOR);
if (StringUtils.isBlank(cache.tenant)) {
listenConfigsBuilder.append(cache.getMd5()).append(LINE_SEPARATOR);
} else {
listenConfigsBuilder.append(cache.getMd5()).append(WORD_SEPARATOR);
listenConfigsBuilder.append(cache.getTenant()).append(LINE_SEPARATOR);
}
if (index >= 3000) {
configStrings.add(listenConfigsBuilder.toString());
listenConfigsBuilder = new StringBuilder();
index = 0;
}
}
if (listenConfigsBuilder.length() > 0) {
configStrings.add(listenConfigsBuilder.toString());
}
return configStrings;
}
/** /**
* build config string. * build config string.
* *
* @param caches caches to build config string. * @param caches caches to build config string.
* @return * @return request.
*/
private String buildConfigStr(List<CacheData> caches) {
StringBuilder listenConfigsBuilder = new StringBuilder();
List<String> configStrings = new ArrayList<String>();
for (CacheData cache : caches) {
listenConfigsBuilder.append(cache.dataId).append(WORD_SEPARATOR);
listenConfigsBuilder.append(cache.group).append(WORD_SEPARATOR);
if (StringUtils.isBlank(cache.tenant)) {
listenConfigsBuilder.append(cache.getMd5()).append(LINE_SEPARATOR);
} else {
listenConfigsBuilder.append(cache.getMd5()).append(WORD_SEPARATOR);
listenConfigsBuilder.append(cache.getTenant()).append(LINE_SEPARATOR);
}
}
return listenConfigsBuilder.toString();
}
/**
* build config string.
*
* @param caches caches to build config string.
* @return
*/ */
private ConfigBatchListenRequest buildConfigRequest(List<CacheData> caches) { private ConfigBatchListenRequest buildConfigRequest(List<CacheData> caches) {
@ -885,7 +850,7 @@ public class ClientWorker implements Closeable {
/** /**
* send cancel listen config change request . * send cancel listen config change request .
* *
* @param configListenString string of remove listen config string. * @param configChangeListenRequest request of remove listen config string.
*/ */
private boolean unListenConfigChange(RpcClient rpcClient, ConfigBatchListenRequest configChangeListenRequest) private boolean unListenConfigChange(RpcClient rpcClient, ConfigBatchListenRequest configChangeListenRequest)
throws NacosException { throws NacosException {
@ -896,11 +861,12 @@ public class ClientWorker implements Closeable {
} }
@Override @Override
public String[] queryConfig(String dataId, String group, String tenant, long readTimeous, boolean notify) public String[] queryConfig(String dataId, String group, String tenant, long readTimeouts, boolean notify)
throws NacosException { throws NacosException {
ConfigQueryRequest request = ConfigQueryRequest.build(dataId, group, tenant); ConfigQueryRequest request = ConfigQueryRequest.build(dataId, group, tenant);
request.putHeader("notify", String.valueOf(notify)); request.putHeader("notify", String.valueOf(notify));
ConfigQueryResponse response = (ConfigQueryResponse) requestProxy(getOneRunningClient(), request); ConfigQueryResponse response = (ConfigQueryResponse) requestProxy(getOneRunningClient(), request,
readTimeouts);
String[] ct = new String[2]; String[] ct = new String[2];
if (response.isSuccess()) { if (response.isSuccess()) {
@ -932,6 +898,11 @@ public class ClientWorker implements Closeable {
} }
private Response requestProxy(RpcClient rpcClientInner, Request request) throws NacosException { private Response requestProxy(RpcClient rpcClientInner, Request request) throws NacosException {
return requestProxy(rpcClientInner, request, 3000L);
}
private Response requestProxy(RpcClient rpcClientInner, Request request, long timeoutMills)
throws NacosException {
try { try {
request.putAllHeader(super.getSecurityHeaders()); request.putAllHeader(super.getSecurityHeaders());
request.putAllHeader(super.getSpasHeaders()); request.putAllHeader(super.getSpasHeaders());
@ -947,7 +918,7 @@ public class ClientWorker implements Closeable {
throw new NacosException(NacosException.CLIENT_OVER_THRESHOLD, throw new NacosException(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold"); "More than client-side current limit threshold");
} }
return rpcClientInner.request(request); return rpcClientInner.request(request, timeoutMills);
} }
RpcClient getOneRunningClient() throws NacosException { RpcClient getOneRunningClient() throws NacosException {
@ -962,7 +933,7 @@ public class ClientWorker implements Closeable {
request.putAdditonalParam("tag", tag); request.putAdditonalParam("tag", tag);
request.putAdditonalParam("appName", appName); request.putAdditonalParam("appName", appName);
request.putAdditonalParam("betaIps", betaIps); request.putAdditonalParam("betaIps", betaIps);
ConfigPubishResponse response = (ConfigPubishResponse) requestProxy(getOneRunningClient(), request); ConfigPublishResponse response = (ConfigPublishResponse) requestProxy(getOneRunningClient(), request);
return response.isSuccess(); return response.isSuccess();
} catch (Exception e) { } catch (Exception e) {
LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}",
@ -972,8 +943,8 @@ public class ClientWorker implements Closeable {
} }
@Override @Override
public boolean removeConfig(String dataid, String group, String tenat, String tag) throws NacosException { public boolean removeConfig(String dataId, String group, String tenant, String tag) throws NacosException {
ConfigRemoveRequest request = new ConfigRemoveRequest(dataid, group, tenat, tag); ConfigRemoveRequest request = new ConfigRemoveRequest(dataId, group, tenant, tag);
ConfigRemoveResponse response = (ConfigRemoveResponse) requestProxy(getOneRunningClient(), request); ConfigRemoveResponse response = (ConfigRemoveResponse) requestProxy(getOneRunningClient(), request);
return response.isSuccess(); return response.isSuccess();
} }
@ -996,7 +967,7 @@ public class ClientWorker implements Closeable {
} }
@Override @Override
public void startIntenal() { public void startInternal() {
executor.scheduleWithFixedDelay(new Runnable() { executor.scheduleWithFixedDelay(new Runnable() {
@Override @Override
@ -1022,14 +993,14 @@ public class ClientWorker implements Closeable {
@Override @Override
public void executeConfigListen() { public void executeConfigListen() {
// Dispatch taskes. // Dispatch tasks.
int listenerSize = cacheMap.get().size(); int listenerSize = cacheMap.get().size();
// Round up the longingTaskCount. // Round up the longingTaskCount.
int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize()); int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
if (longingTaskCount > currentLongingTaskCount) { if (longingTaskCount > currentLongingTaskCount) {
for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) { for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
// The task list is no order.So it maybe has issues when changing. // The task list is no order.So it maybe has issues when changing.
executorService.execute(new LongPollingRunnable(agent, i, this)); executor.execute(new LongPollingRunnable(agent, i, this));
} }
currentLongingTaskCount = longingTaskCount; currentLongingTaskCount = longingTaskCount;
} }
@ -1313,8 +1284,9 @@ public class ClientWorker implements Closeable {
tenant = key[2]; tenant = key[2];
} }
try { try {
String[] ct = getServerConfig(dataId, group, tenant, 3000L, true);
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant)); CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
String[] ct = getServerConfig(dataId, group, tenant, 3000L, !cache.isInitializing());
cache.setContent(ct[0]); cache.setContent(ct[0]);
if (null != ct[1]) { if (null != ct[1]) {
cache.setType(ct[1]); cache.setType(ct[1]);
@ -1338,13 +1310,13 @@ public class ClientWorker implements Closeable {
} }
inInitializingCacheList.clear(); inInitializingCacheList.clear();
executorService.execute(this); configTransportClient.executor.execute(this);
} catch (Throwable e) { } catch (Throwable e) {
// If the rotation training task is abnormal, the next execution time of the task will be punished // If the rotation training task is abnormal, the next execution time of the task will be punished
LOGGER.error("longPolling error : ", e); LOGGER.error("longPolling error : ", e);
executorService.schedule(this, taskPenaltyTime, TimeUnit.MILLISECONDS); configTransportClient.executor.schedule(this, taskPenaltyTime, TimeUnit.MILLISECONDS);
} }
} }
} }
@ -1499,7 +1471,7 @@ public class ClientWorker implements Closeable {
/** /**
* get client worker agent. * get client worker agent.
* *
* @return * @return agent name.
*/ */
public String getAgentName() { public String getAgentName() {
return this.agent.getName(); return this.agent.getName();

View File

@ -131,7 +131,7 @@ public abstract class ConfigTransportClient {
/** /**
* get common header. * get common header.
* *
* @return * @return headers.
*/ */
protected Map<String, String> getCommonHeader() { protected Map<String, String> getCommonHeader() {
Map<String, String> headers = new HashMap<String, String>(16); Map<String, String> headers = new HashMap<String, String>(16);
@ -244,7 +244,7 @@ public abstract class ConfigTransportClient {
} }
startIntenal(); startInternal();
} }
/** /**
@ -252,7 +252,7 @@ public abstract class ConfigTransportClient {
* *
* @throws NacosException exception may throw. * @throws NacosException exception may throw.
*/ */
public abstract void startIntenal() throws NacosException; public abstract void startInternal() throws NacosException;
/** /**
* get client name. * get client name.
@ -264,7 +264,7 @@ public abstract class ConfigTransportClient {
/** /**
* get encode. * get encode.
* *
* @return * @return encode.
*/ */
public String getEncode() { public String getEncode() {
return this.encode; return this.encode;
@ -273,7 +273,7 @@ public abstract class ConfigTransportClient {
/** /**
* get tenant. * get tenant.
* *
* @return * @return tenant.
*/ */
public String getTenant() { public String getTenant() {
return this.tenant; return this.tenant;
@ -286,8 +286,6 @@ public abstract class ConfigTransportClient {
/** /**
* listen change . * listen change .
*
* @return
*/ */
public abstract void executeConfigListen(); public abstract void executeConfigListen();

View File

@ -211,7 +211,7 @@ public class ParamUtils {
/** /**
* check whether still using http . * check whether still using http .
* *
* @return * @return use http transport .
*/ */
public static boolean useHttpSwitch() { public static boolean useHttpSwitch() {
String useHttpSwitch = System.getProperty("clientworker.use.http.switch"); String useHttpSwitch = System.getProperty("clientworker.use.http.switch");
@ -221,7 +221,7 @@ public class ParamUtils {
/** /**
* get connection type for remote. * get connection type for remote.
* *
* @return * @return connection type.
*/ */
public static String configRemoteConnectionType() { public static String configRemoteConnectionType() {
String remoteConnectionType = System.getProperty("nacos.remote.config.connectiontype"); String remoteConnectionType = System.getProperty("nacos.remote.config.connectiontype");

View File

@ -31,22 +31,8 @@
<DefaultRolloverStrategy max="${sys:JM.LOG.RETAIN.COUNT:-7}"/> <DefaultRolloverStrategy max="${sys:JM.LOG.RETAIN.COUNT:-7}"/>
</RollingFile> </RollingFile>
<RollingFile name="REMOTE_LOG_FILE" fileName="${sys:JM.LOG.PATH}/rpc.log" <RollingFile name="REMOTE_LOG_FILE" fileName="${sys:JM.LOG.PATH}/nacos/remote.log"
filePattern="${sys:JM.LOG.PATH}/rpc.log.%d{yyyy-MM-dd}.%i"> filePattern="${sys:JM.LOG.PATH}/nacos/remote.log.%d{yyyy-MM-dd}.%i">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${sys:JM.LOG.FILE.SIZE:-10MB}"/>
</Policies>
<DefaultRolloverStrategy max="${sys:JM.LOG.RETAIN.COUNT:-7}"/>
</RollingFile>
<RollingFile name="GRPC_LOG_FILE" fileName="${sys:JM.LOG.PATH}/grpc.log"
filePattern="${sys:JM.LOG.PATH}/grpc.log.%d{yyyy-MM-dd}.%i">
<PatternLayout> <PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern>
</PatternLayout> </PatternLayout>
@ -85,12 +71,6 @@
<AppenderRef ref="REMOTE_LOG_FILE"/> <AppenderRef ref="REMOTE_LOG_FILE"/>
</Logger> </Logger>
<Logger name="com.alibaba.nacos.client.grpc" level="${sys:com.alibaba.nacos.grpc.log.level:-info}"
additivity="false">
<AppenderRef ref="GRPC_LOG_FILE"/>
</Logger>
<Logger name="com.alibaba.nacos.client.config" level="${sys:com.alibaba.nacos.config.log.level:-info}" <Logger name="com.alibaba.nacos.client.config" level="${sys:com.alibaba.nacos.config.log.level:-info}"
additivity="false"> additivity="false">
<AppenderRef ref="CONFIG_LOG_FILE"/> <AppenderRef ref="CONFIG_LOG_FILE"/>

View File

@ -53,10 +53,10 @@
</appender> </appender>
<appender name="REMOTE_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="REMOTE_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${JM.LOG.PATH}/remote.log</file> <file>${JM.LOG.PATH}/nacos/remote.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${JM.LOG.PATH}/remote.log.%i</fileNamePattern> <fileNamePattern>${JM.LOG.PATH}/nacos/remote.log.%i</fileNamePattern>
<maxIndex>${JM.LOG.RETAIN.COUNT:-7}</maxIndex> <maxIndex>${JM.LOG.RETAIN.COUNT:-7}</maxIndex>
</rollingPolicy> </rollingPolicy>
@ -76,9 +76,9 @@
</logger> </logger>
<Logger name="com.alibaba.nacos.common.remote.client" level="${sys:com.alibaba.nacos.config.log.level:-info}" <Logger name="com.alibaba.nacos.common.remote.client" level="${com.alibaba.nacos.log.level:-info}"
additivity="false"> additivity="false">
<AppenderRef ref="REMOTE_LOG_FILE"/> <appender-ref ref="REMOTE_LOG_FILE"/>
</Logger> </Logger>

View File

@ -24,6 +24,7 @@ import com.alibaba.nacos.api.remote.RequestFuture;
import com.alibaba.nacos.api.remote.request.ConnectResetRequest; import com.alibaba.nacos.api.remote.request.ConnectResetRequest;
import com.alibaba.nacos.api.remote.request.Request; import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.api.remote.request.ServerCheckRequest;
import com.alibaba.nacos.api.remote.response.ConnectResetResponse; import com.alibaba.nacos.api.remote.response.ConnectResetResponse;
import com.alibaba.nacos.api.remote.response.ConnectionUnregisterResponse; import com.alibaba.nacos.api.remote.response.ConnectionUnregisterResponse;
import com.alibaba.nacos.api.remote.response.Response; import com.alibaba.nacos.api.remote.response.Response;
@ -60,7 +61,7 @@ import static com.alibaba.nacos.api.exception.NacosException.SERVER_ERROR;
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") @SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class RpcClient implements Closeable { public abstract class RpcClient implements Closeable {
private static final Logger LOGGER = LoggerFactory.getLogger(RpcClient.class); private static final Logger LOGGER = LoggerFactory.getLogger("com.alibaba.nacos.common.remote.client");
private ServerListFactory serverListFactory; private ServerListFactory serverListFactory;
@ -69,7 +70,7 @@ public abstract class RpcClient implements Closeable {
protected volatile AtomicReference<RpcClientStatus> rpcClientStatus = new AtomicReference<RpcClientStatus>( protected volatile AtomicReference<RpcClientStatus> rpcClientStatus = new AtomicReference<RpcClientStatus>(
RpcClientStatus.WAIT_INIT); RpcClientStatus.WAIT_INIT);
protected ScheduledExecutorService executorService; protected ScheduledExecutorService executor;
protected volatile Connection currentConnection; protected volatile Connection currentConnection;
@ -77,6 +78,10 @@ public abstract class RpcClient implements Closeable {
private String name; private String name;
private static final int RETRY_TIMES = 3;
private static final long DEFAULT_TIMEOUT_MILLS = 3000L;
/** /**
* listener called where connect status changed. * listener called where connect status changed.
*/ */
@ -127,7 +132,12 @@ public abstract class RpcClient implements Closeable {
} }
LoggerUtils.printIfInfoEnabled(LOGGER, "Notify disconnected event to listeners"); LoggerUtils.printIfInfoEnabled(LOGGER, "Notify disconnected event to listeners");
for (ConnectionEventListener connectionEventListener : connectionEventListeners) { for (ConnectionEventListener connectionEventListener : connectionEventListeners) {
try {
connectionEventListener.onDisConnect(); connectionEventListener.onDisConnect();
} catch (Throwable throwable) {
LoggerUtils.printIfErrorEnabled(LOGGER, "notify disconnect listener error,listener ={}",
connectionEventListener.getClass().getName());
}
} }
} }
@ -140,7 +150,12 @@ public abstract class RpcClient implements Closeable {
} }
LoggerUtils.printIfInfoEnabled(LOGGER, "Notify connected event to listeners."); LoggerUtils.printIfInfoEnabled(LOGGER, "Notify connected event to listeners.");
for (ConnectionEventListener connectionEventListener : connectionEventListeners) { for (ConnectionEventListener connectionEventListener : connectionEventListeners) {
try {
connectionEventListener.onConnected(); connectionEventListener.onConnected();
} catch (Throwable throwable) {
LoggerUtils.printIfErrorEnabled(LOGGER, "notify connect listener error,listener ={}",
connectionEventListener.getClass().getName());
}
} }
} }
@ -207,7 +222,7 @@ public abstract class RpcClient implements Closeable {
return; return;
} }
executorService = new ScheduledThreadPoolExecutor(5, new ThreadFactory() { executor = new ScheduledThreadPoolExecutor(0, new ThreadFactory() {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r); Thread t = new Thread(r);
@ -218,7 +233,7 @@ public abstract class RpcClient implements Closeable {
}); });
// connection event consumer. // connection event consumer.
executorService.submit(new Runnable() { executor.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
while (true) { while (true) {
@ -241,7 +256,7 @@ public abstract class RpcClient implements Closeable {
Connection connectToServer = null; Connection connectToServer = null;
rpcClientStatus.set(RpcClientStatus.STARTING); rpcClientStatus.set(RpcClientStatus.STARTING);
int startUpRetryTimes = 3; int startUpRetryTimes = RETRY_TIMES;
while (startUpRetryTimes > 0 && connectToServer == null) { while (startUpRetryTimes > 0 && connectToServer == null) {
try { try {
startUpRetryTimes--; startUpRetryTimes--;
@ -268,38 +283,7 @@ public abstract class RpcClient implements Closeable {
switchServerAsync(); switchServerAsync();
} }
registerServerPushResponseHandler(new ServerRequestHandler() { registerServerPushResponseHandler(new ConnectResetRequestHandler());
@Override
public Response requestReply(Request request, RequestMeta requestMeta) {
if (request instanceof ConnectResetRequest) {
try {
synchronized (this) {
if (isRunning()) {
ConnectResetRequest connectResetRequest = (ConnectResetRequest) request;
if (StringUtils.isNotBlank(connectResetRequest.getServerIp()) && NumberUtil
.isDigits(connectResetRequest.getServerPort())) {
ServerInfo serverInfo = new ServerInfo();
serverInfo.setServerIp(connectResetRequest.getServerIp());
serverInfo.setServerPort(
Integer.valueOf(connectResetRequest.getServerPort()) + rpcPortOffset());
switchServerAsync(serverInfo);
} else {
switchServerAsync();
}
}
}
} catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "Switch server error ", e);
}
return new ConnectResetResponse();
}
return null;
}
});
Runtime.getRuntime().addShutdownHook(new Thread() { Runtime.getRuntime().addShutdownHook(new Thread() {
@Override @Override
public void run() { public void run() {
@ -314,9 +298,43 @@ public abstract class RpcClient implements Closeable {
} }
class ConnectResetRequestHandler implements ServerRequestHandler {
@Override
public Response requestReply(Request request, RequestMeta requestMeta) {
if (request instanceof ConnectResetRequest) {
try {
synchronized (RpcClient.this) {
if (isRunning()) {
ConnectResetRequest connectResetRequest = (ConnectResetRequest) request;
if (StringUtils.isNotBlank(connectResetRequest.getServerIp()) && NumberUtil
.isDigits(connectResetRequest.getServerPort())) {
ServerInfo serverInfo = new ServerInfo();
serverInfo.setServerIp(connectResetRequest.getServerIp());
serverInfo.setServerPort(
Integer.valueOf(connectResetRequest.getServerPort()) + rpcPortOffset());
switchServerAsync(serverInfo, false);
} else {
switchServerAsync();
}
}
}
} catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "Switch server error ", e);
}
return new ConnectResetResponse();
}
return null;
}
}
@Override @Override
public void shutdown() throws NacosException { public void shutdown() throws NacosException {
executorService.shutdown(); executor.shutdown();
rpcClientStatus.set(RpcClientStatus.SHUTDOWN); rpcClientStatus.set(RpcClientStatus.SHUTDOWN);
closeConnection(currentConnection); closeConnection(currentConnection);
} }
@ -325,20 +343,38 @@ public abstract class RpcClient implements Closeable {
private volatile AtomicBoolean switchingFlag = new AtomicBoolean(false); private volatile AtomicBoolean switchingFlag = new AtomicBoolean(false);
private boolean serverCheck() {
ServerCheckRequest serverCheckRequest = new ServerCheckRequest();
try {
Response response = this.currentConnection.request(serverCheckRequest, buildMeta());
return response == null ? false : response.isSuccess();
} catch (NacosException e) {
//ignore
}
return false;
}
public void switchServerAsyncOnRequestFail() {
switchServerAsync(null, true);
}
public void switchServerAsync() { public void switchServerAsync() {
switchServerAsync(null); switchServerAsync(null, false);
} }
/** /**
* switch server . * switch server .
*/ */
protected void switchServerAsync(final ServerInfo recommendServerInfo) { protected void switchServerAsync(final ServerInfo recommendServerInfo, boolean onRequestFail) {
//return if is in switching of other thread. //return if is in switching of other thread.
if (switchingFlag.get()) { if (switchingFlag.get()) {
return; return;
} }
executorService.submit(new Runnable() { LoggerUtils.printIfInfoEnabled(LOGGER,
String.format("[%s] Submit server switch task : %s,onRequestFail=%s", name, recommendServerInfo,
onRequestFail));
executor.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -350,6 +386,17 @@ public abstract class RpcClient implements Closeable {
if (!innerLock) { if (!innerLock) {
return; return;
} }
if (onRequestFail && serverCheck()) {
LoggerUtils.printIfInfoEnabled(LOGGER,
String.format("[%s] Server check success : %s", name, recommendServer));
rpcClientStatus.set(RpcClientStatus.RUNNING);
return;
}
LoggerUtils.printIfInfoEnabled(LOGGER,
String.format("[%s] Execute server switch task : %s", name, recommendServer));
switchingFlag.compareAndSet(false, true); switchingFlag.compareAndSet(false, true);
// loop until start client success. // loop until start client success.
boolean switchSuccess = false; boolean switchSuccess = false;
@ -361,20 +408,20 @@ public abstract class RpcClient implements Closeable {
//1.get a new server //1.get a new server
ServerInfo serverInfo = null; ServerInfo serverInfo = null;
//2.create a new channel to new server
try { try {
serverInfo = recommendServer.get() == null ? nextRpcServer() : recommendServer.get(); serverInfo = recommendServer.get() == null ? nextRpcServer() : recommendServer.get();
//2.create a new channel to new server
Connection connectNew = connectToServer(serverInfo); Connection connectionNew = connectToServer(serverInfo);
if (connectNew != null) { if (connectionNew != null) {
LoggerUtils.printIfInfoEnabled(LOGGER, LoggerUtils.printIfInfoEnabled(LOGGER,
String.format("[%s] success to connect server : %s", name, serverInfo)); String.format("[%s] success to connect server : %s", name, serverInfo));
//successfully create a new connect. //successfully create a new connect.
if (currentConnection != null) { if (currentConnection != null) {
//set current connection to enable connection event.
currentConnection.setAbandon(true); currentConnection.setAbandon(true);
closeConnection(currentConnection); closeConnection(currentConnection);
} }
currentConnection = connectNew; currentConnection = connectionNew;
rpcClientStatus.set(RpcClientStatus.RUNNING); rpcClientStatus.set(RpcClientStatus.RUNNING);
switchSuccess = true; switchSuccess = true;
boolean s = eventLinkedBlockingQueue boolean s = eventLinkedBlockingQueue
@ -382,9 +429,9 @@ public abstract class RpcClient implements Closeable {
return; return;
} }
//close connetion if client is already shutdown. //close connection if client is already shutdown.
if (isShutdown()) { if (isShutdown()) {
closeConnection(connectNew); closeConnection(currentConnection);
} }
lastException = null; lastException = null;
@ -401,7 +448,7 @@ public abstract class RpcClient implements Closeable {
"[%s] fail to connect server,after trying %s times, last try server is %s", name, "[%s] fail to connect server,after trying %s times, last try server is %s", name,
reConnectTimes, serverInfo)); reConnectTimes, serverInfo));
if (Integer.MAX_VALUE == retryTurns) { if (Integer.MAX_VALUE == retryTurns) {
retryTurns = 10; retryTurns = 50;
} else { } else {
retryTurns++; retryTurns++;
} }
@ -410,10 +457,10 @@ public abstract class RpcClient implements Closeable {
reConnectTimes++; reConnectTimes++;
try { try {
//sleep 100 millsecond to switch next server. //sleep x milliseconds to switch next server.
if (!isRunning()) { if (!isRunning()) {
// first round ,try servers at a delay 100ms;second round ,200ms; max delays 1s. to be reconsidered.基本上会快速收敛到几个可用的IP // first round ,try servers at a delay 100ms;second round ,200ms; max delays 5s. to be reconsidered.
Thread.sleep(Math.min(retryTurns + 1, 10) * 100L); Thread.sleep(Math.min(retryTurns + 1, 50) * 100L);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
// Do nothing. // Do nothing.
@ -475,7 +522,7 @@ public abstract class RpcClient implements Closeable {
* @return response from server. * @return response from server.
*/ */
public Response request(Request request) throws NacosException { public Response request(Request request) throws NacosException {
return request(request, 3000L); return request(request, DEFAULT_TIMEOUT_MILLS);
} }
/** /**
@ -485,13 +532,14 @@ public abstract class RpcClient implements Closeable {
* @return response from server. * @return response from server.
*/ */
public Response request(Request request, long timeoutMills) throws NacosException { public Response request(Request request, long timeoutMills) throws NacosException {
int retryTimes = 3; int retryTimes = 1;
Response response = null; Response response = null;
Exception exceptionToThrow = null; Exception exceptionToThrow = null;
while (retryTimes > 0) { long start = System.currentTimeMillis();
while (retryTimes < RETRY_TIMES && (System.currentTimeMillis() - start) < timeoutMills) {
try { try {
if (this.currentConnection == null || !isRunning()) { if (this.currentConnection == null || !isRunning()) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected."); throw new NacosException(NacosException.CLIENT_DISCONNECT, "Client not connected.");
} }
response = this.currentConnection.request(request, buildMeta()); response = this.currentConnection.request(request, buildMeta());
@ -509,50 +557,69 @@ public abstract class RpcClient implements Closeable {
} }
} catch (Exception e) { } catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "Fail to send request, request={}, errorMessage={}", request,
e.getMessage());
exceptionToThrow = e; exceptionToThrow = e;
if (e instanceof NacosException
&& ((NacosException) e).getErrCode() == NacosException.CLIENT_DISCONNECT) {
// Do nothing.
} else {
LoggerUtils
.printIfErrorEnabled(LOGGER, "send request fail, request={}, retryTimes={},errorMessage={}",
request, retryTimes, e.getMessage());
} }
retryTimes--; }
retryTimes++;
} }
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) { if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
switchServerAsync(); switchServerAsyncOnRequestFail();
} }
if (exceptionToThrow != null) { if (exceptionToThrow != null) {
throw new NacosException(SERVER_ERROR, exceptionToThrow); throw (exceptionToThrow instanceof NacosException) ? (NacosException) exceptionToThrow
: new NacosException(SERVER_ERROR, exceptionToThrow);
} }
return null; return null;
} }
/** /**
* send aync request. * send async request.
* *
* @param request request. * @param request request.
*/ */
public void asyncRequest(Request request, RequestCallBack callback) throws NacosException { public void asyncRequest(Request request, RequestCallBack callback) throws NacosException {
int retryTimes = 3; int retryTimes = 0;
Exception exceptionToThrow = null; Exception exceptionToThrow = null;
while (retryTimes > 0) { long start = System.currentTimeMillis();
while (retryTimes < RETRY_TIMES && System.currentTimeMillis() > start + callback.getTimeout()) {
try { try {
if (this.currentConnection == null) { if (this.currentConnection == null || !isRunning()) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected."); throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected.");
} }
this.currentConnection.asyncRequest(request, buildMeta(), callback); this.currentConnection.asyncRequest(request, buildMeta(), callback);
return; return;
} catch (Exception e) { } catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "Fail to send request, request={}, error Message={}", request,
e.getMessage());
exceptionToThrow = e; exceptionToThrow = e;
if (e instanceof NacosException
&& ((NacosException) e).getErrCode() == NacosException.CLIENT_DISCONNECT) {
// Do nothing.
} else {
LoggerUtils
.printIfErrorEnabled(LOGGER, "send request fail, request={}, retryTimes={},errorMessage={}",
request, retryTimes, e.getMessage());
} }
retryTimes--; }
retryTimes++;
} }
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
switchServerAsyncOnRequestFail();
}
if (exceptionToThrow != null) { if (exceptionToThrow != null) {
throw new NacosException(SERVER_ERROR, exceptionToThrow); throw (exceptionToThrow instanceof NacosException) ? (NacosException) exceptionToThrow
: new NacosException(SERVER_ERROR, exceptionToThrow);
} }
} }
@ -563,11 +630,38 @@ public abstract class RpcClient implements Closeable {
* @return request future. * @return request future.
*/ */
public RequestFuture requestFuture(Request request) throws NacosException { public RequestFuture requestFuture(Request request) throws NacosException {
if (this.currentConnection == null) { int retryTimes = 0;
long start = System.currentTimeMillis();
Exception exceptionToThrow = null;
while (retryTimes < RETRY_TIMES && System.currentTimeMillis() > start + DEFAULT_TIMEOUT_MILLS) {
try {
if (this.currentConnection == null || !isRunning()) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected."); throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected.");
} }
RequestFuture requestFuture = this.currentConnection.requestFuture(request, buildMeta()); RequestFuture requestFuture = this.currentConnection.requestFuture(request, buildMeta());
return requestFuture; return requestFuture;
} catch (Exception e) {
exceptionToThrow = e;
if (e instanceof NacosException
&& ((NacosException) e).getErrCode() == NacosException.CLIENT_DISCONNECT) {
// Do nothing.
} else {
LoggerUtils
.printIfErrorEnabled(LOGGER, "send request fail, request={}, retryTimes={},errorMessage={}",
request, retryTimes, e.getMessage());
}
}
}
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
switchServerAsyncOnRequestFail();
}
if (exceptionToThrow != null) {
throw (exceptionToThrow instanceof NacosException) ? (NacosException) exceptionToThrow
: new NacosException(SERVER_ERROR, exceptionToThrow);
}
return null;
} }
@ -588,11 +682,19 @@ public abstract class RpcClient implements Closeable {
*/ */
protected Response handleServerRequest(final Request request, final RequestMeta meta) { protected Response handleServerRequest(final Request request, final RequestMeta meta) {
LoggerUtils.printIfInfoEnabled(LOGGER, "receive server push request,request={},requestId={}",
request.getClass().getSimpleName(), request.getRequestId());
for (ServerRequestHandler serverRequestHandler : serverRequestHandlers) { for (ServerRequestHandler serverRequestHandler : serverRequestHandlers) {
try {
Response response = serverRequestHandler.requestReply(request, meta); Response response = serverRequestHandler.requestReply(request, meta);
if (response != null) { if (response != null) {
return response; return response;
} }
} catch (Exception e) {
LoggerUtils.printIfInfoEnabled(LOGGER, "handleServerRequest:{}, errorMessage={}",
serverRequestHandler.getClass().getName(), e.getMessage());
}
} }
return null; return null;
} }

View File

@ -68,7 +68,7 @@ public class RpcClientFactory {
* *
* @param clientName client name. * @param clientName client name.
* @param connectionType client type. * @param connectionType client type.
* @return * @return rpc client.
*/ */
public static RpcClient createClient(String clientName, ConnectionType connectionType, Map<String, String> labels) { public static RpcClient createClient(String clientName, ConnectionType connectionType, Map<String, String> labels) {
String clientNameInner = clientName; String clientNameInner = clientName;
@ -97,7 +97,7 @@ public class RpcClientFactory {
* *
* @param clientName client name. * @param clientName client name.
* @param connectionType client type. * @param connectionType client type.
* @return * @return rpc client.
*/ */
public static RpcClient createClusterClient(String clientName, ConnectionType connectionType, public static RpcClient createClusterClient(String clientName, ConnectionType connectionType,
Map<String, String> labels) { Map<String, String> labels) {

View File

@ -28,20 +28,20 @@ public interface ServerListFactory {
/** /**
* switch to a new server and get it. * switch to a new server and get it.
* *
* @return * @return server " ip:port".
*/ */
String genNextServer(); String genNextServer();
/** /**
* get current server. * get current server.
* @return * @return server " ip:port".
*/ */
String getCurrentServer(); String getCurrentServer();
/** /**
* get current server. * get current server.
* *
* @return * @return servers.
*/ */
List<String> getServerList(); List<String> getServerList();

View File

@ -34,6 +34,7 @@ import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder; import io.grpc.ManagedChannelBuilder;
import io.grpc.Status; import io.grpc.Status;
import io.grpc.StatusRuntimeException; import io.grpc.StatusRuntimeException;
import io.grpc.internal.GrpcUtil;
import io.grpc.stub.StreamObserver; import io.grpc.stub.StreamObserver;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -70,8 +71,9 @@ public abstract class GrpcClient extends RpcClient {
*/ */
private RequestGrpc.RequestFutureStub createNewChannelStub(String serverIp, int serverPort) { private RequestGrpc.RequestFutureStub createNewChannelStub(String serverIp, int serverPort) {
ManagedChannel managedChannelTemp = ManagedChannelBuilder.forAddress(serverIp, serverPort).usePlaintext() ManagedChannelBuilder<?> o = ManagedChannelBuilder.forAddress(serverIp, serverPort)
.build(); .executor(GrpcUtil.SHARED_CHANNEL_EXECUTOR.create()).usePlaintext();
ManagedChannel managedChannelTemp = o.build();
RequestGrpc.RequestFutureStub grpcServiceStubTemp = RequestGrpc.newFutureStub(managedChannelTemp); RequestGrpc.RequestFutureStub grpcServiceStubTemp = RequestGrpc.newFutureStub(managedChannelTemp);
@ -131,6 +133,7 @@ public abstract class GrpcClient extends RpcClient {
GrpcUtils.PlainRequest parse = GrpcUtils.parse(payload); GrpcUtils.PlainRequest parse = GrpcUtils.parse(payload);
final Request request = (Request) parse.getBody(); final Request request = (Request) parse.getBody();
if (request != null) { if (request != null) {
try { try {
Response response = handleServerRequest(request, parse.metadata); Response response = handleServerRequest(request, parse.metadata);
if (response != null) { if (response != null) {
@ -146,6 +149,7 @@ public abstract class GrpcClient extends RpcClient {
payload.toString()); payload.toString());
sendResponse(request.getRequestId(), false); sendResponse(request.getRequestId(), false);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -157,8 +161,10 @@ public abstract class GrpcClient extends RpcClient {
@Override @Override
public void onError(Throwable throwable) { public void onError(Throwable throwable) {
if (isRunning() && !grpcConn.isAbandon()) { boolean isRunning = isRunning();
LoggerUtils.printIfErrorEnabled(LOGGER, "Request stream error, switch server", throwable); boolean isAbandon = grpcConn.isAbandon();
if (isRunning && !isAbandon) {
LoggerUtils.printIfErrorEnabled(LOGGER, "Request stream error, switch server,error={}", throwable);
if (throwable instanceof StatusRuntimeException) { if (throwable instanceof StatusRuntimeException) {
Status.Code code = ((StatusRuntimeException) throwable).getStatus().getCode(); Status.Code code = ((StatusRuntimeException) throwable).getStatus().getCode();
if (Status.UNAVAILABLE.getCode().equals(code) || Status.CANCELLED.getCode().equals(code)) { if (Status.UNAVAILABLE.getCode().equals(code) || Status.CANCELLED.getCode().equals(code)) {
@ -168,20 +174,24 @@ public abstract class GrpcClient extends RpcClient {
} }
} }
} else { } else {
LoggerUtils.printIfWarnEnabled(LOGGER, "Client is not running status, ignore error event"); LoggerUtils.printIfWarnEnabled(LOGGER, "ignore error event,isRunning:{},isAbandon={}", isRunning,
isAbandon);
} }
} }
@Override @Override
public void onCompleted() { public void onCompleted() {
if (isRunning() && !grpcConn.isAbandon()) { boolean isRunning = isRunning();
boolean isAbandon = grpcConn.isAbandon();
if (isRunning && !isAbandon) {
LoggerUtils.printIfErrorEnabled(LOGGER, "Request stream onCompleted, switch server"); LoggerUtils.printIfErrorEnabled(LOGGER, "Request stream onCompleted, switch server");
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) { if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
switchServerAsync(); switchServerAsync();
} }
} else { } else {
LoggerUtils.printIfErrorEnabled(LOGGER, "Client is not running status, ignore complete event"); LoggerUtils.printIfInfoEnabled(LOGGER, "ignore complete event,isRunning:{},isAbandon={}", isRunning,
isAbandon);
} }
} }
@ -215,7 +225,7 @@ public abstract class GrpcClient extends RpcClient {
BiRequestStreamGrpc.BiRequestStreamStub biRequestStreamStub = BiRequestStreamGrpc BiRequestStreamGrpc.BiRequestStreamStub biRequestStreamStub = BiRequestStreamGrpc
.newStub(newChannelStubTemp.getChannel()); .newStub(newChannelStubTemp.getChannel());
GrpcConnection grpcConn = new GrpcConnection(serverInfo); GrpcConnection grpcConn = new GrpcConnection(serverInfo, super.executor);
//create stream request and bind connection event to this connection. //create stream request and bind connection event to this connection.
StreamObserver<Payload> payloadStreamObserver = bindRequestStream(biRequestStreamStub, grpcConn); StreamObserver<Payload> payloadStreamObserver = bindRequestStream(biRequestStreamStub, grpcConn);

View File

@ -37,6 +37,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableDecl;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -53,6 +54,8 @@ public class GrpcConnection extends Connection {
*/ */
protected ManagedChannel channel; protected ManagedChannel channel;
Executor executor;
/** /**
* stub to send request. * stub to send request.
*/ */
@ -60,8 +63,9 @@ public class GrpcConnection extends Connection {
protected StreamObserver<Payload> payloadStreamObserver; protected StreamObserver<Payload> payloadStreamObserver;
public GrpcConnection(RpcClient.ServerInfo serverInfo) { public GrpcConnection(RpcClient.ServerInfo serverInfo, Executor executor) {
super(serverInfo); super(serverInfo);
this.executor = executor;
} }
@Override @Override
@ -72,7 +76,6 @@ public class GrpcConnection extends Connection {
@Override @Override
public Response request(Request request, RequestMeta requestMeta, long timeouts) throws NacosException { public Response request(Request request, RequestMeta requestMeta, long timeouts) throws NacosException {
Payload grpcRequest = GrpcUtils.convert(request, requestMeta); Payload grpcRequest = GrpcUtils.convert(request, requestMeta);
ListenableFuture<Payload> requestFuture = grpcFutureServiceStub.request(grpcRequest); ListenableFuture<Payload> requestFuture = grpcFutureServiceStub.request(grpcRequest);
Payload grpcResponse = null; Payload grpcResponse = null;
try { try {
@ -155,16 +158,16 @@ public class GrpcConnection extends Connection {
public void onFailure(Throwable throwable) { public void onFailure(Throwable throwable) {
if (throwable instanceof CancellationException) { if (throwable instanceof CancellationException) {
requestCallBack.onException( requestCallBack.onException(
new TimeoutException("Timeout after " + requestCallBack.getTimeout() + " millseconds.")); new TimeoutException("Timeout after " + requestCallBack.getTimeout() + " milliseconds."));
} else { } else {
requestCallBack.onException(throwable); requestCallBack.onException(throwable);
} }
} }
}, RpcScheduledExecutor.AYNS_REQUEST_EXECUTOR); }, this.executor);
// set timeout future. // set timeout future.
ListenableFuture<Payload> payloadListenableFuture = Futures ListenableFuture<Payload> payloadListenableFuture = Futures
.withTimeout(requestFuture, requestCallBack.getTimeout(), TimeUnit.MILLISECONDS, .withTimeout(requestFuture, requestCallBack.getTimeout(), TimeUnit.MILLISECONDS,
RpcScheduledExecutor.TIMEOUT_SHEDULER); RpcScheduledExecutor.TIMEOUT_SCHEDULER);
} }

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.common.remote.client.grpc; package com.alibaba.nacos.common.remote.client.grpc;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException; import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException;
import com.alibaba.nacos.api.exception.runtime.NacosSerializationException; import com.alibaba.nacos.api.exception.runtime.NacosSerializationException;
import com.alibaba.nacos.api.grpc.auto.Metadata; import com.alibaba.nacos.api.grpc.auto.Metadata;
@ -24,6 +26,7 @@ import com.alibaba.nacos.api.remote.PayloadRegistry;
import com.alibaba.nacos.api.remote.request.Request; import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.api.remote.response.Response; import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.common.remote.exception.RemoteException;
import com.alibaba.nacos.common.utils.VersionUtils; import com.alibaba.nacos.common.utils.VersionUtils;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
@ -33,6 +36,7 @@ import com.google.protobuf.Any;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset;
/** /**
* grpc utils, use to parse request and response. * grpc utils, use to parse request and response.
@ -86,7 +90,7 @@ public class GrpcUtils {
* *
* @param request request. * @param request request.
* @param meta request meta. * @param meta request meta.
* @return * @return payload.
*/ */
public static Payload convert(Request request, RequestMeta meta) { public static Payload convert(Request request, RequestMeta meta) {
//meta. //meta.
@ -103,8 +107,9 @@ public class GrpcUtils {
// request body . // request body .
request.clearHeaders(); request.clearHeaders();
String jsonString = toJson(request); String jsonString = toJson(request);
Payload payload = builder
Payload payload = builder.setBody(Any.newBuilder().setValue(ByteString.copyFromUtf8(jsonString))).build(); .setBody(Any.newBuilder().setValue(ByteString.copyFrom(jsonString, Charset.forName(Constants.ENCODE))))
.build();
return payload; return payload;
} }
@ -114,7 +119,7 @@ public class GrpcUtils {
* *
* @param request request. * @param request request.
* @param meta meta * @param meta meta
* @return * @return payload.
*/ */
public static Payload convert(Request request, Metadata meta) { public static Payload convert(Request request, Metadata meta) {
@ -123,9 +128,9 @@ public class GrpcUtils {
String jsonString = toJson(request); String jsonString = toJson(request);
Payload.Builder builder = Payload.newBuilder(); Payload.Builder builder = Payload.newBuilder();
Payload payload = builder.setBody(Any.newBuilder().setValue(ByteString.copyFromUtf8(jsonString))) Payload payload = builder
.setMetadata(buildMeta) .setBody(Any.newBuilder().setValue(ByteString.copyFrom(jsonString, Charset.forName(Constants.ENCODE))))
.build(); .setMetadata(buildMeta).build();
return payload; return payload;
} }
@ -134,7 +139,7 @@ public class GrpcUtils {
* convert response to payload. * convert response to payload.
* *
* @param response response. * @param response response.
* @return * @return payload.
*/ */
public static Payload convert(Response response) { public static Payload convert(Response response) {
String jsonString = toJson(response); String jsonString = toJson(response);
@ -142,7 +147,8 @@ public class GrpcUtils {
Metadata.Builder metaBuilder = Metadata.newBuilder(); Metadata.Builder metaBuilder = Metadata.newBuilder();
metaBuilder.setClientVersion(VersionUtils.getFullClientVersion()).setType(response.getClass().getName()); metaBuilder.setClientVersion(VersionUtils.getFullClientVersion()).setType(response.getClass().getName());
Payload payload = Payload.newBuilder().setBody(Any.newBuilder().setValue(ByteString.copyFromUtf8(jsonString))) Payload payload = Payload.newBuilder()
.setBody(Any.newBuilder().setValue(ByteString.copyFrom(jsonString, Charset.forName(Constants.ENCODE))))
.setMetadata(metaBuilder.build()).build(); .setMetadata(metaBuilder.build()).build();
return payload; return payload;
} }
@ -151,17 +157,19 @@ public class GrpcUtils {
* parse payload to request/response model. * parse payload to request/response model.
* *
* @param payload payload to be parsed. * @param payload payload to be parsed.
* @return * @return payload
*/ */
public static PlainRequest parse(Payload payload) { public static PlainRequest parse(Payload payload) {
PlainRequest plainRequest = new PlainRequest(); PlainRequest plainRequest = new PlainRequest();
Class classbyType = PayloadRegistry.getClassByType(payload.getMetadata().getType()); Class classyType = PayloadRegistry.getClassByType(payload.getMetadata().getType());
if (classbyType != null) { if (classyType != null) {
Object obj = toObj(payload.getBody().getValue().toStringUtf8(), classbyType); Object obj = toObj(payload.getBody().getValue().toString(Charset.forName(Constants.ENCODE)), classyType);
if (obj instanceof Request) { if (obj instanceof Request) {
((Request) obj).putAllHeader(payload.getMetadata().getHeadersMap()); ((Request) obj).putAllHeader(payload.getMetadata().getHeadersMap());
} }
plainRequest.body = obj; plainRequest.body = obj;
} else {
throw new RemoteException(NacosException.SERVER_ERROR, "unknown payload type:" + classyType);
} }
plainRequest.type = payload.getMetadata().getType(); plainRequest.type = payload.getMetadata().getType();

View File

@ -122,7 +122,7 @@ public class RsocketConnection extends Connection {
private static <T> CompletableFuture<T> failAfter(final long timeouts) { private static <T> CompletableFuture<T> failAfter(final long timeouts) {
final CompletableFuture<T> promise = new CompletableFuture<T>(); final CompletableFuture<T> promise = new CompletableFuture<T>();
RpcScheduledExecutor.TIMEOUT_SHEDULER.schedule(new Callable<Object>() { RpcScheduledExecutor.TIMEOUT_SCHEDULER.schedule(new Callable<Object>() {
@Override @Override
public Object call() throws Exception { public Object call() throws Exception {
final TimeoutException ex = new TimeoutException("Timeout after " + timeouts); final TimeoutException ex = new TimeoutException("Timeout after " + timeouts);

View File

@ -109,7 +109,7 @@ public class IoUtils {
* *
* @param str strings to be compressed. * @param str strings to be compressed.
* @param encoding encoding. * @param encoding encoding.
* @return * @return byte[]
*/ */
public static byte[] tryCompress(String str, String encoding) { public static byte[] tryCompress(String str, String encoding) {
if (str == null || str.length() == 0) { if (str == null || str.length() == 0) {

View File

@ -185,7 +185,7 @@ public class ConfigController {
} }
/** /**
* Get configure board infomation fail. * Get configure board information fail.
* *
* @throws ServletException ServletException. * @throws ServletException ServletException.
* @throws IOException IOException. * @throws IOException IOException.

View File

@ -17,7 +17,7 @@
package com.alibaba.nacos.config.server.remote; package com.alibaba.nacos.config.server.remote;
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest; import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
import com.alibaba.nacos.api.config.remote.response.ConfigPubishResponse; import com.alibaba.nacos.api.config.remote.response.ConfigPublishResponse;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.auth.annotation.Secured;
@ -49,7 +49,7 @@ import java.util.Map;
* @version $Id: ConfigPublishRequestHandler.java, v 0.1 2020年07月16日 4:41 PM liuzunfei Exp $ * @version $Id: ConfigPublishRequestHandler.java, v 0.1 2020年07月16日 4:41 PM liuzunfei Exp $
*/ */
@Component @Component
public class ConfigPublishRequestHandler extends RequestHandler<ConfigPublishRequest, ConfigPubishResponse> { public class ConfigPublishRequestHandler extends RequestHandler<ConfigPublishRequest, ConfigPublishResponse> {
private final PersistService persistService; private final PersistService persistService;
@ -59,7 +59,7 @@ public class ConfigPublishRequestHandler extends RequestHandler<ConfigPublishReq
@Override @Override
@Secured(action = ActionTypes.WRITE, resource = "", parser = ConfigResourceParser.class) @Secured(action = ActionTypes.WRITE, resource = "", parser = ConfigResourceParser.class)
public ConfigPubishResponse handle(ConfigPublishRequest request, RequestMeta meta) throws NacosException { public ConfigPublishResponse handle(ConfigPublishRequest request, RequestMeta meta) throws NacosException {
try { try {
String dataId = request.getDataId(); String dataId = request.getDataId();
@ -115,10 +115,10 @@ public class ConfigPublishRequestHandler extends RequestHandler<ConfigPublishReq
ConfigTraceService ConfigTraceService
.logPersistenceEvent(dataId, group, tenant, requestIpApp, time.getTime(), InetUtils.getSelfIP(), .logPersistenceEvent(dataId, group, tenant, requestIpApp, time.getTime(), InetUtils.getSelfIP(),
ConfigTraceService.PERSISTENCE_EVENT_PUB, content); ConfigTraceService.PERSISTENCE_EVENT_PUB, content);
return ConfigPubishResponse.buildSuccessResponse(); return ConfigPublishResponse.buildSuccessResponse();
} catch (Exception e) { } catch (Exception e) {
Loggers.REMOTE_DIGEST.error("[ConfigPublishRequestHandler] publish config error ,request ={}", request, e); Loggers.REMOTE_DIGEST.error("[ConfigPublishRequestHandler] publish config error ,request ={}", request, e);
return ConfigPubishResponse.buildFailResponse(e.getMessage()); return ConfigPublishResponse.buildFailResponse(e.getMessage());
} }
} }

View File

@ -41,11 +41,13 @@ import org.springframework.stereotype.Component;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static com.alibaba.nacos.config.server.utils.LogUtil.PULL_LOG; import static com.alibaba.nacos.config.server.utils.LogUtil.PULL_LOG;
@ -231,7 +233,7 @@ public class ConfigQueryRequestHandler extends RequestHandler<ConfigQueryRequest
because the delayed value of active get requests is very large. because the delayed value of active get requests is very large.
*/ */
ConfigTraceService.logPullEvent(dataId, group, tenant, requestIpApp, lastModified, ConfigTraceService.logPullEvent(dataId, group, tenant, requestIpApp, lastModified,
ConfigTraceService.PULL_EVENT_OK, delayed, clientIp, notify); ConfigTraceService.PULL_EVENT_OK, notify ? delayed : -1, clientIp, notify);
} finally { } finally {
releaseConfigReadLock(groupKey); releaseConfigReadLock(groupKey);
@ -256,13 +258,15 @@ public class ConfigQueryRequestHandler extends RequestHandler<ConfigQueryRequest
* read content. * read content.
* *
* @param file file to read. * @param file file to read.
* @return * @return content.
*/ */
public static String readFileContent(File file) { public static String readFileContent(File file) {
BufferedReader reader = null; BufferedReader reader = null;
StringBuffer sbf = new StringBuffer(); StringBuffer sbf = new StringBuffer();
try { try {
reader = new BufferedReader(new FileReader(file)); InputStreamReader isr = new InputStreamReader(new FileInputStream(file), Charset.forName(Constants.ENCODE));
reader = new BufferedReader(isr);
String tempStr; String tempStr;
while ((tempStr = reader.readLine()) != null) { while ((tempStr = reader.readLine()) != null) {
sbf.append(tempStr); sbf.append(tempStr);

View File

@ -72,7 +72,7 @@ public abstract class BaseRpcServer {
/** /**
* get connection type. * get connection type.
* *
* @return * @return connection type.
*/ */
public abstract ConnectionType getConnectionType(); public abstract ConnectionType getConnectionType();
@ -86,14 +86,14 @@ public abstract class BaseRpcServer {
/** /**
* the increase offset of nacos server port for rpc server port. * the increase offset of nacos server port for rpc server port.
* *
* @return * @return delta port offset of main port.
*/ */
public abstract int rpcPortOffset(); public abstract int rpcPortOffset();
/** /**
* get service port. * get service port.
* *
* @return * @return service port.
*/ */
public int getServicePort() { public int getServicePort() {
return EnvUtil.getPort() + rpcPortOffset(); return EnvUtil.getPort() + rpcPortOffset();
@ -111,7 +111,6 @@ public abstract class BaseRpcServer {
/** /**
* the increase offset of nacos server port for rpc server port. * the increase offset of nacos server port for rpc server port.
* *
* @return
*/ */
public abstract void shutdownServer(); public abstract void shutdownServer();

View File

@ -30,7 +30,7 @@ import javax.annotation.PostConstruct;
public abstract class ClientConnectionEventListener { public abstract class ClientConnectionEventListener {
/** /**
* lisnter name. * listener name.
*/ */
private String name; private String name;

View File

@ -21,10 +21,6 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/** /**
* registry for client connection event listeners. * registry for client connection event listeners.
@ -37,30 +33,24 @@ public class ClientConnectionEventListenerRegistry {
final List<ClientConnectionEventListener> clientConnectionEventListeners = new ArrayList<ClientConnectionEventListener>(); final List<ClientConnectionEventListener> clientConnectionEventListeners = new ArrayList<ClientConnectionEventListener>();
protected ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.core.remote.client.connection.notifier");
t.setDaemon(true);
return t;
}
});
/** /**
* notify where a new client connected. * notify where a new client connected.
* *
* @param connection connection that new created. * @param connection connection that new created.
*/ */
public void notifyClientConnected(final Connection connection) { public void notifyClientConnected(final Connection connection) {
executorService.schedule(new Runnable() {
@Override
public void run() {
for (ClientConnectionEventListener clientConnectionEventListener : clientConnectionEventListeners) { for (ClientConnectionEventListener clientConnectionEventListener : clientConnectionEventListeners) {
try {
clientConnectionEventListener.clientConnected(connection); clientConnectionEventListener.clientConnected(connection);
} catch (Throwable throwable) {
Loggers.REMOTE
.info("[NotifyClientConnected] failed for listener {}", clientConnectionEventListener.getName(),
throwable);
} }
} }
}, 0L, TimeUnit.MILLISECONDS);
} }
/** /**
@ -69,18 +59,16 @@ public class ClientConnectionEventListenerRegistry {
* @param connection connection that disconnected. * @param connection connection that disconnected.
*/ */
public void notifyClientDisConnected(final Connection connection) { public void notifyClientDisConnected(final Connection connection) {
executorService.schedule(new Runnable() {
@Override for (ClientConnectionEventListener clientConnectionEventListener : clientConnectionEventListeners) {
public void run() {
for (ClientConnectionEventListener each : clientConnectionEventListeners) {
try { try {
each.clientDisConnected(connection); clientConnectionEventListener.clientDisConnected(connection);
} catch (Exception e) { } catch (Throwable throwable) {
Loggers.REMOTE.info("[NotifyClientDisConnected] failed for listener {}", each.getName(), e); Loggers.REMOTE.info("[NotifyClientDisConnected] failed for listener {}",
clientConnectionEventListener.getName(), throwable);
} }
} }
}
}, 0L, TimeUnit.MILLISECONDS);
} }
/** /**

View File

@ -162,7 +162,7 @@ public class ConnectionManager {
@PostConstruct @PostConstruct
public void start() { public void start() {
// Start UnHeathy Conection Expel Task. // Start UnHealthy Connection Expel Task.
RpcScheduledExecutor.COMMON_SERVER_EXECUTOR.scheduleWithFixedDelay(new Runnable() { RpcScheduledExecutor.COMMON_SERVER_EXECUTOR.scheduleWithFixedDelay(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -215,7 +215,7 @@ public class ConnectionManager {
} }
} catch (Throwable e) { } catch (Throwable e) {
Loggers.REMOTE.error("error occurs when heathy check... ", e); Loggers.REMOTE.error("error occurs when healthy check... ", e);
} }
} }
}, 1000L, 3000L, TimeUnit.MILLISECONDS); }, 1000L, 3000L, TimeUnit.MILLISECONDS);
@ -268,7 +268,7 @@ public class ConnectionManager {
/** /**
* get all client count. * get all client count.
* *
* @return * @return client count.
*/ */
public int currentClientsCount() { public int currentClientsCount() {
return connections.size(); return connections.size();
@ -322,7 +322,7 @@ public class ConnectionManager {
/** /**
* check if over limit. * check if over limit.
* *
* @return * @return over limit or not.
*/ */
public boolean isOverLimit() { public boolean isOverLimit() {
return maxClient > 0 && this.connections.size() >= maxClient; return maxClient > 0 && this.connections.size() >= maxClient;

View File

@ -41,10 +41,10 @@ public class RequestHandlerRegistry implements ApplicationContextAware {
Map<String, RequestHandler> registryHandlers = new HashMap<String, RequestHandler>(); Map<String, RequestHandler> registryHandlers = new HashMap<String, RequestHandler>();
/** /**
* Get Reuquest Handler By request Type. * Get Request Handler By request Type.
* *
* @param requestType see definitions of sub constants classes of RequestTypeConstants * @param requestType see definitions of sub constants classes of RequestTypeConstants
* @return * @return request handler.
*/ */
public RequestHandler getByRequestType(String requestType) { public RequestHandler getByRequestType(String requestType) {
if (!registryHandlers.containsKey(requestType)) { if (!registryHandlers.containsKey(requestType)) {

View File

@ -131,7 +131,7 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
.set(TRANS_KEY_CONN_ID, UuidUtils.generateUuid()).set(TRANS_KEY_CLIENT_PORT, remotePort) .set(TRANS_KEY_CONN_ID, UuidUtils.generateUuid()).set(TRANS_KEY_CLIENT_PORT, remotePort)
.set(TRANS_KEY_LOCAL_PORT, localPort).build(); .set(TRANS_KEY_LOCAL_PORT, localPort).build();
String connectionId = attrWrapper.get(TRANS_KEY_CONN_ID); String connectionId = attrWrapper.get(TRANS_KEY_CONN_ID);
Loggers.REMOTE.info("Connection transportReady, connectionId = {}", connectionId); Loggers.REMOTE_DIGEST.info("Connection transportReady,connectionId = {} ", connectionId);
return attrWrapper; return attrWrapper;
} }
@ -139,7 +139,7 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
@Override @Override
public void transportTerminated(Attributes transportAttrs) { public void transportTerminated(Attributes transportAttrs) {
String connectionId = transportAttrs.get(TRANS_KEY_CONN_ID); String connectionId = transportAttrs.get(TRANS_KEY_CONN_ID);
Loggers.REMOTE.info("Connection transportTerminated, connectionId = {}", connectionId); Loggers.REMOTE_DIGEST.info("Connection transportTerminated,connectionId = {} ", connectionId);
connectionManager.unregister(connectionId); connectionManager.unregister(connectionId);
} }
}).build(); }).build();

View File

@ -60,7 +60,7 @@ public class RsocketConnection extends Connection {
private static <T> CompletableFuture<T> failAfter(final long timeouts) { private static <T> CompletableFuture<T> failAfter(final long timeouts) {
final CompletableFuture<T> promise = new CompletableFuture<T>(); final CompletableFuture<T> promise = new CompletableFuture<T>();
RpcScheduledExecutor.TIMEOUT_SHEDULER.schedule(new Callable<Object>() { RpcScheduledExecutor.TIMEOUT_SCHEDULER.schedule(new Callable<Object>() {
@Override @Override
public Object call() throws Exception { public Object call() throws Exception {
final TimeoutException ex = new TimeoutException("Timeout after " + timeouts); final TimeoutException ex = new TimeoutException("Timeout after " + timeouts);

View File

@ -36,7 +36,7 @@ public class StringPool {
* get singleton string value from the pool. * get singleton string value from the pool.
* *
* @param key key string to be pooled. * @param key key string to be pooled.
* @return * @return value after pooled.
*/ */
public static String get(String key) { public static String get(String key) {
if (key == null) { if (key == null) {