org.bdware.doip.cluster.util.DoipClientCacheUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of doip-audit-tool Show documentation
Show all versions of doip-audit-tool Show documentation
doip audit tool developed by bdware
The newest version!
package org.bdware.doip.cluster.util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.doip.audit.client.AuditDoipClient;
import org.bdware.doip.audit.writer.AuditConfig;
import org.bdware.doip.audit.writer.AuditType;
import org.bdware.doip.cluster.callback.AutoCancelReconnectCallback;
import org.bdware.doip.cluster.callback.ClientReadyCallback;
import org.bdware.doip.cluster.entity.BDOEntity;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DoipClientCacheUtil {
static Logger LOGGER = LogManager.getLogger(DoipClientCacheUtil.class);
public DoipClientCacheUtil() {
}
private final Map clientCache = new ConcurrentHashMap<>();
private final ExecutorService connectionTaskPool = Executors.newFixedThreadPool(8, r -> {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
});
private void tryReconnect(AuditDoipClient doipClientImpl, long timeToWait, ClientReadyCallback callback) {
connectionTaskPool.execute(() -> {
AutoCancelReconnectCallback autoCancelReconnectCallback = new AutoCancelReconnectCallback(doipClientImpl, callback, (int) timeToWait / 1000);
try {
doipClientImpl.rwLock.acquire();
if (!doipClientImpl.isConnected()) {
//LOGGER.info("=========ACTUALLY try reconnect to:" + doipClientImpl.getRepoUrl() + " tid:" + Thread.currentThread().getId());
doipClientImpl.reconnect();
//LOGGER.info("=========ACTUALLY SUCCESS:" + doipClientImpl.getRepoUrl() + " tid:" + Thread.currentThread().getId());
}
} catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bo));
LOGGER.info("failed to connect to:" + doipClientImpl.getRepoUrl() + " " + bo);
} finally {
doipClientImpl.rwLock.release();
autoCancelReconnectCallback.onReady(doipClientImpl);
}
});
}
public void popReconnectRequest(AuditDoipClient doipClient) {
if (doipClient != null) {
doipClient.decreaseTimeoutCount();
}
}
public void pushReconnectRequest(AuditDoipClient doipClient) {
if (doipClient != null) {
if (doipClient.needReconnect()) {
doipClient.disconnectAndSet(doipClient.getRepoUrl());
tryReconnect(doipClient, 10000, null);
}
}
}
private void getClientByUrlInternal(BDOEntity bdoEntity, AuditConfig config, ClientReadyCallback callback) {
if (bdoEntity.getAddress() == null && bdoEntity.getVersion() == null) callback.onReady(null);
AuditDoipClient doipClientImpl = clientCache.get(bdoEntity.getAddress());
if (doipClientImpl == null) {
// Create the client only if it doesn't exist in the map
doipClientImpl = createWithoutConnect(bdoEntity, config);
// Use putIfAbsent() to ensure thread-safety
AuditDoipClient existingClient = clientCache.putIfAbsent(bdoEntity.getAddress(), doipClientImpl);
if (existingClient != null) {
// If another thread added a client while we were creating ours, use that instead
doipClientImpl = existingClient;
}
}
if (doipClientImpl.isConnected()) {
callback.onReady(doipClientImpl);
return;
}
try {
// Always try to reconnect, regardless of whether the client was just created or already existed
tryReconnect(doipClientImpl, 2000, callback);
} catch (Exception e) {
e.printStackTrace();
}
}
public void getClientByUrl(BDOEntity bdoEntity, AuditConfig config, ClientReadyCallback callback) {
AuditDoipClient doipClientImpl = clientCache.get(bdoEntity.getAddress());
if (doipClientImpl != null && doipClientImpl.isConnected()) {
callback.onReady(doipClientImpl);
return;
}
//重新排个队去发起重连的请求
// new RequestPackIntf(){
// @Override
// public void run() {
// getClientByUrlInternal(bdoEntity, config, callback);
// }
// @Override
// public long getPriority() {
// return 100;
// }
// }.execute();
getClientByUrlInternal(bdoEntity, config, callback);
}
private static AuditDoipClient createWithoutConnect(BDOEntity bdoEntity, AuditConfig config) {
if (config == null) AuditConfig.newInstance(null, AuditType.None, null);
AuditDoipClient doipClientImpl = new AuditDoipClient(config, null);
LOGGER.info("connect to:" + bdoEntity.getAddress());
doipClientImpl.setRepoUrl(bdoEntity.getAddress());
return doipClientImpl;
}
public void closeAll() {
for (AuditDoipClient client : clientCache.values()) {
try {
if (client.isConnected()) client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
clientCache.clear();
}
}