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

org.rx.net.rpc.impl.RpcClientPoolImpl Maven / Gradle / Ivy

package org.rx.net.rpc.impl;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.rx.core.Disposable;
import org.rx.net.rpc.RpcClientConfig;
import org.rx.net.rpc.RpcClientPool;

@Slf4j
@RequiredArgsConstructor
public class RpcClientPoolImpl extends Disposable implements RpcClientPool {
    private final GenericObjectPool pool;

    public RpcClientPoolImpl(RpcClientConfig template) {
        int minSize = Math.max(2, template.getMinPoolSize());
        int maxSize = Math.max(minSize, template.getMaxPoolSize());
        GenericObjectPoolConfig config = new GenericObjectPoolConfig<>();
        config.setLifo(true);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);
        config.setJmxEnabled(false);
        config.setMaxWaitMillis(template.getConnectTimeoutMillis());
        config.setMinIdle(minSize);
        config.setMaxIdle(maxSize);
        config.setMaxTotal(maxSize);
        pool = new GenericObjectPool<>(new BasePooledObjectFactory() {
            @Override
            public StatefulRpcClient create() throws Exception {
                RpcClientConfig config = template.deepClone();
                StatefulRpcClient client = new StatefulRpcClient(config);
                client.connect(true);
                log.debug("Create RpcClient {}", client);
                return client;
            }

            @Override
            public PooledObject wrap(StatefulRpcClient client) {
                return new DefaultPooledObject<>(client);
            }

            @Override
            public boolean validateObject(PooledObject p) {
                return p.getObject().isConnected();
            }

            @Override
            public void destroyObject(PooledObject p) throws Exception {
                p.getObject().close();
            }

            @Override
            public void passivateObject(PooledObject p) throws Exception {
                StatefulRpcClient client = p.getObject();
                client.getConfig().setEnableReconnect(false);
                client.onError.purge();
                client.onReceive.purge();
                client.onSend.purge();
                client.onDisconnected.purge();
                client.onConnected.purge();
                client.onReconnected.purge();
                client.onReconnecting.purge();
            }
        }, config);
    }

    @Override
    protected void freeObjects() {
        pool.close();
    }

    @SneakyThrows
    @Override
    public StatefulRpcClient borrowClient() {
        checkNotClosed();

        StatefulRpcClient client = pool.borrowObject();
        log.debug("Take RpcClient {}", client);
        return client;
    }

    @SneakyThrows
    @Override
    public StatefulRpcClient returnClient(StatefulRpcClient client) {
        checkNotClosed();

        try {
            if (!client.getConfig().isEnableReconnect() && !client.isConnected()) {
                pool.invalidateObject(client);
                return null;
            }

            pool.returnObject(client); //对同一对象会return多次hang
        } catch (IllegalStateException e) {
            log.warn("returnClient", e);
        }
        log.debug("Return RpcClient {}", client);
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy