Package com.relayrides.pushy.apns

Source Code of com.relayrides.pushy.apns.BenchmarkApp$BenchmarkErrorListener

/* Copyright (c) 2014 RelayRides
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.relayrides.pushy.apns;

import io.netty.channel.nio.NioEventLoopGroup;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import com.relayrides.pushy.apns.util.ApnsPayloadBuilder;
import com.relayrides.pushy.apns.util.SimpleApnsPushNotification;

public class BenchmarkApp {

  private static final int NOTIFICATIONS_PER_TEST = 100000;

  private static final int GATEWAY_PORT = 2195;
  private static final int FEEDPACK_PORT = 2196;

  private static final ApnsEnvironment BENCHMARK_ENVIRONMENT =
      new ApnsEnvironment("127.0.0.1", GATEWAY_PORT, "localhost", FEEDPACK_PORT);

  private NioEventLoopGroup serverEventLoopGroup;
  private MockApnsServer server;

  private final ArrayList<SimpleApnsPushNotification> notifications =
      new ArrayList<SimpleApnsPushNotification>(NOTIFICATIONS_PER_TEST);

  private class BenchmarkErrorListener implements RejectedNotificationListener<SimpleApnsPushNotification>, FailedConnectionListener<SimpleApnsPushNotification> {

    @Override
    public void handleFailedConnection(final PushManager<? extends SimpleApnsPushNotification> pushManager, final Throwable cause) {
      System.err.println("Connection failed.");
      cause.printStackTrace(System.err);
    }

    @Override
    public void handleRejectedNotification(final PushManager<? extends SimpleApnsPushNotification> pushManager, final SimpleApnsPushNotification notification, final RejectedNotificationReason rejectionReason) {
      System.err.format("%s rejected: %s\n", notification, rejectionReason);
    }
  }

  public BenchmarkApp() throws Exception {
    final ApnsPayloadBuilder builder = new ApnsPayloadBuilder();
    final Random random = new Random();

    for (int i = 0; i < NOTIFICATIONS_PER_TEST; i++) {
      final byte[] token = new byte[32];
      random.nextBytes(token);

      builder.setAlertBody(new BigInteger(1024, new Random()).toString(16));

      this.notifications.add(new SimpleApnsPushNotification(token, builder.buildWithDefaultMaximumLength()));
    }
  }

  public void runAllBenchmarks() throws InterruptedException {
    this.serverEventLoopGroup = new NioEventLoopGroup(2);
    this.server = new MockApnsServer(GATEWAY_PORT, serverEventLoopGroup);

    // We want to do a dummy run first to let the JVM warm up
    final NioEventLoopGroup warmupGroup = new NioEventLoopGroup(1);
    this.runBenchmark(warmupGroup, 1, this.notifications);
    warmupGroup.shutdownGracefully().await();

    System.out.println("threads, connections, throughput [k/sec]");

    for (int eventLoopGroupThreadCount : new int[] {1, 2, 4, 8, 16}) {
      final NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(eventLoopGroupThreadCount);

      for (int concurrentConnectionCount : new int[] {1, 2, 4, 8, 16, 32}) {
        if (concurrentConnectionCount >= eventLoopGroupThreadCount) {
          System.gc();

          double throughput = this.runBenchmark(eventLoopGroup, concurrentConnectionCount, this.notifications);

          System.out.format("%d, %d, %.1f\n",
              eventLoopGroupThreadCount,
              concurrentConnectionCount,
              throughput / 1000.0);
        }
      }

      eventLoopGroup.shutdownGracefully().await();
    }

    this.serverEventLoopGroup.shutdownGracefully().await();
  }

  private double runBenchmark(final NioEventLoopGroup eventLoopGroup, final int concurrentConnectionCount, final List<SimpleApnsPushNotification> notifications) throws InterruptedException {
    final PushManagerConfiguration configuration = new PushManagerConfiguration();
    configuration.setConcurrentConnectionCount(concurrentConnectionCount);

    final PushManager<SimpleApnsPushNotification> pushManager;

    try {
      pushManager = new PushManager<SimpleApnsPushNotification>(BENCHMARK_ENVIRONMENT,
          SSLTestUtil.createSSLContextForTestClient(), eventLoopGroup, null, null, configuration,
          "Benchmark push manager");
    } catch (Exception e) {
      throw new RuntimeException("Failed to create push manager.", e);
    }

    final BenchmarkErrorListener errorListener = new BenchmarkErrorListener();

    pushManager.registerFailedConnectionListener(errorListener);
    pushManager.registerRejectedNotificationListener(errorListener);
    pushManager.getQueue().addAll(notifications);

    final CountDownLatch firstMessageLatch = this.server.getAcceptedNotificationCountDownLatch(1);
    final CountDownLatch lastMessageLatch = this.server.getAcceptedNotificationCountDownLatch(notifications.size());

    this.server.start();
    pushManager.start();

    if (!firstMessageLatch.await(10, TimeUnit.SECONDS)) {
      System.err.println("Timed out waiting for first message.");
    }

    long start = System.currentTimeMillis();

    if (!lastMessageLatch.await(10, TimeUnit.SECONDS)) {
      System.err.println("Timed out waiting for last message. Remaining count: " + lastMessageLatch.getCount());
    }

    long end = System.currentTimeMillis();

    pushManager.shutdown();
    this.server.shutdown();

    return 1000.0 * ((double)notifications.size() / (double)(end - start));
  }

  public static void main(String[] args) throws Exception {
    final BenchmarkApp benchmarkApp = new BenchmarkApp();
    benchmarkApp.runAllBenchmarks();
  }
}
TOP

Related Classes of com.relayrides.pushy.apns.BenchmarkApp$BenchmarkErrorListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.