All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bdware.doip.cluster.util.DoipClientCacheUtil Maven / Gradle / Ivy

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();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy