/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
- /*
- * Copyright 2009, Mahmood Ali.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Mahmood Ali. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- package com.notnoop.apns.internal;
- import java.util.concurrent.*;
- import com.notnoop.apns.ApnsNotification;
- import com.notnoop.exceptions.NetworkIOException;
- import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class ApnsPooledConnection implements ApnsConnection {
- private static final Logger logger = LoggerFactory.getLogger(ApnsPooledConnection.class);
- private final ApnsConnection prototype;
- private final int max;
- private final ExecutorService executors;
- private final ConcurrentLinkedQueue<ApnsConnection> prototypes;
- public ApnsPooledConnection(ApnsConnection prototype, int max) {
- this(prototype, max, Executors.newFixedThreadPool(max));
- }
- public ApnsPooledConnection(ApnsConnection prototype, int max, ExecutorService executors) {
- this.prototype = prototype;
- this.max = max;
- this.executors = executors;
- this.prototypes = new ConcurrentLinkedQueue<ApnsConnection>();
- }
- private final ThreadLocal<ApnsConnection> uniquePrototype =
- new ThreadLocal<ApnsConnection>() {
- protected ApnsConnection initialValue() {
- ApnsConnection newCopy = prototype.copy();
- prototypes.add(newCopy);
- return newCopy;
- }
- };
- public void sendMessage(final ApnsNotification m) throws NetworkIOException {
- Future<Void> future = executors.submit(new Callable<Void>() {
- public Void call() throws Exception {
- uniquePrototype.get().sendMessage(m);
- return null;
- }
- });
- try {
- future.get();
- } catch (InterruptedException ie) {
- Thread.currentThread().interrupt();
- } catch (ExecutionException ee) {
- if (ee.getCause() instanceof NetworkIOException) {
- throw (NetworkIOException) ee.getCause();
- }
- }
- }
- public ApnsConnection copy() {
- // TODO: Should copy executor properly.... What should copy do
- // really?!
- return new ApnsPooledConnection(prototype, max);
- }
- public void close() {
- executors.shutdown();
- try {
- executors.awaitTermination(10, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- logger.warn("pool termination interrupted", e);
- }
- for (ApnsConnection conn : prototypes) {
- Utilities.close(conn);
- }
- Utilities.close(prototype);
- }
- public void testConnection() {
- prototype.testConnection();
- }
- public synchronized void setCacheLength(int cacheLength) {
- for (ApnsConnection conn : prototypes) {
- conn.setCacheLength(cacheLength);
- }
- }
- @SuppressFBWarnings(value = "UG_SYNC_SET_UNSYNC_GET", justification = "prototypes is a MT-safe container")
- public int getCacheLength() {
- return prototypes.peek().getCacheLength();
- }
- }