net.sheehantech.cherry.pool.PooledPushClient.java Source code

Java tutorial

Introduction

Here is the source code for net.sheehantech.cherry.pool.PooledPushClient.java

Source

/*
 * This file is part of Cherry.
 *
 * Cherry is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cherry is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cherry.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package net.sheehantech.cherry.pool;

import net.sheehantech.cherry.*;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class PooledPushClient extends AbstractAsyncPushClient {

    private Logger logger = LoggerFactory.getLogger(PooledPushClient.class);

    private GenericObjectPool<PooledPushSocket> pool;
    private Integer maxTotal;
    private Integer minIdle;
    private Integer maxIdle;
    private ExecutorService executor;

    public PooledPushClient(SSLContext sslContext) {
        super(sslContext);
        executor = Executors.newCachedThreadPool();
    }

    public Integer getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(Integer maxTotal) {
        this.maxTotal = maxTotal;
    }

    public Integer getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(Integer maxIdle) {
        this.maxIdle = maxIdle;
    }

    public Integer getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    @Override
    public void init() throws ConnectionFailedException {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        if (maxTotal != null)
            config.setMaxTotal(maxTotal);
        if (maxIdle != null)
            config.setMaxIdle(maxIdle);
        if (minIdle != null)
            config.setMinIdle(minIdle);
        config.setTestOnBorrow(true);
        config.setTestWhileIdle(true);
        config.setBlockWhenExhausted(true);
        pool = new GenericObjectPool<PooledPushSocket>(new PooledPushSocketFactory(socketFactory, gateway, port),
                config);
        try {
            pool.preparePool();
        } catch (Exception e) {
            throw (new ConnectionFailedException(e));
        }
        logger.debug("Started new push socket pool with {} sockets", pool.getNumIdle());
    }

    @Override
    public void shutdown() {
        while (!pool.isClosed()) {
            if (pool.getNumActive() == 0) {
                pool.close();
                logger.info("Shut down pool");
            } else {
                try {
                    logger.debug("Waiting for {} active sockets", pool.getNumActive());
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    logger.debug("Interrrupted during graceful shutdown");
                }
            }
        }
    }

    @Override
    public void shutdownNow() {
        pool.close();
    }

    @Override
    public Future<PushResult> send(Notification notification) throws PushFailedException {
        try {
            notification.setId(nextId());
            Future<PushResult> pushResultFuture = executor
                    .submit(new PooledSendNotificationTask(pool, notification));
            logger.debug("Sent notification {}", notification.getId());
            return pushResultFuture;
        } catch (Exception e) {
            throw (new PushFailedException(e));
        }
    }

}