PageRenderTime 37ms CodeModel.GetById 25ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

/src/main/java/com/notnoop/apns/internal/ApnsPooledConnection.java

http://github.com/notnoop/java-apns
Java | 121 lines | 75 code | 14 blank | 32 comment | 3 complexity | 16a9f92d28c44a01364a10a7324cd186 MD5 | raw file
  1/*
  2 *  Copyright 2009, Mahmood Ali.
  3 *  All rights reserved.
  4 *
  5 *  Redistribution and use in source and binary forms, with or without
  6 *  modification, are permitted provided that the following conditions are
  7 *  met:
  8 *
  9 *    * Redistributions of source code must retain the above copyright
 10 *      notice, this list of conditions and the following disclaimer.
 11 *    * Redistributions in binary form must reproduce the above
 12 *      copyright notice, this list of conditions and the following disclaimer
 13 *      in the documentation and/or other materials provided with the
 14 *      distribution.
 15 *    * Neither the name of Mahmood Ali. nor the names of its
 16 *      contributors may be used to endorse or promote products derived from
 17 *      this software without specific prior written permission.
 18 *
 19 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 20 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 21 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 22 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 23 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 24 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 25 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 26 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 27 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 28 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 29 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 30 */
 31package com.notnoop.apns.internal;
 32
 33import java.util.concurrent.*;
 34import com.notnoop.apns.ApnsNotification;
 35import com.notnoop.exceptions.NetworkIOException;
 36import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 37import org.slf4j.Logger;
 38import org.slf4j.LoggerFactory;
 39
 40public class ApnsPooledConnection implements ApnsConnection {
 41    private static final Logger logger = LoggerFactory.getLogger(ApnsPooledConnection.class);
 42
 43    private final ApnsConnection prototype;
 44    private final int max;
 45
 46    private final ExecutorService executors;
 47    private final ConcurrentLinkedQueue<ApnsConnection> prototypes;
 48
 49    public ApnsPooledConnection(ApnsConnection prototype, int max) {
 50        this(prototype, max, Executors.newFixedThreadPool(max));
 51    }
 52
 53    public ApnsPooledConnection(ApnsConnection prototype, int max, ExecutorService executors) {
 54        this.prototype = prototype;
 55        this.max = max;
 56
 57        this.executors = executors;
 58        this.prototypes = new ConcurrentLinkedQueue<ApnsConnection>();
 59    }
 60
 61    private final ThreadLocal<ApnsConnection> uniquePrototype =
 62        new ThreadLocal<ApnsConnection>() {
 63        protected ApnsConnection initialValue() {
 64            ApnsConnection newCopy = prototype.copy();
 65            prototypes.add(newCopy);
 66            return newCopy;
 67        }
 68    };
 69
 70    public void sendMessage(final ApnsNotification m) throws NetworkIOException {
 71        Future<Void> future = executors.submit(new Callable<Void>() {
 72            public Void call() throws Exception {
 73                uniquePrototype.get().sendMessage(m);
 74                return null;
 75            }
 76        });
 77        try {
 78            future.get();
 79        } catch (InterruptedException ie) {
 80            Thread.currentThread().interrupt();
 81        } catch (ExecutionException ee) {
 82            if (ee.getCause() instanceof NetworkIOException) {
 83                throw (NetworkIOException) ee.getCause();
 84            }
 85        }
 86    }
 87
 88    public ApnsConnection copy() {
 89        // TODO: Should copy executor properly.... What should copy do
 90        // really?!
 91        return new ApnsPooledConnection(prototype, max);
 92    }
 93
 94    public void close() {
 95        executors.shutdown();
 96        try {
 97            executors.awaitTermination(10, TimeUnit.SECONDS);
 98        } catch (InterruptedException e) {
 99            logger.warn("pool termination interrupted", e);
100        }
101        for (ApnsConnection conn : prototypes) {
102            Utilities.close(conn);
103        }
104        Utilities.close(prototype);
105    }
106
107    public void testConnection() {
108        prototype.testConnection();
109    }
110
111    public synchronized void setCacheLength(int cacheLength) {  
112        for (ApnsConnection conn : prototypes) {
113            conn.setCacheLength(cacheLength);
114        }
115    }
116
117    @SuppressFBWarnings(value = "UG_SYNC_SET_UNSYNC_GET", justification = "prototypes is a MT-safe container")
118    public int getCacheLength() {
119        return prototypes.peek().getCacheLength();
120    }
121}