1/*
2 * Copyright (C) 2014 Square, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.squareup.okhttp.benchmarks;
17
18import com.squareup.okhttp.Dispatcher;
19import com.squareup.okhttp.Failure;
20import com.squareup.okhttp.OkHttpClient;
21import com.squareup.okhttp.Request;
22import com.squareup.okhttp.Response;
23import com.squareup.okhttp.internal.SslContextBuilder;
24import java.io.IOException;
25import java.net.URL;
26import java.util.concurrent.LinkedBlockingQueue;
27import java.util.concurrent.ThreadPoolExecutor;
28import java.util.concurrent.TimeUnit;
29import java.util.concurrent.atomic.AtomicInteger;
30import javax.net.ssl.HostnameVerifier;
31import javax.net.ssl.SSLContext;
32import javax.net.ssl.SSLSession;
33import javax.net.ssl.SSLSocketFactory;
34
35class OkHttpAsync implements HttpClient {
36  private static final boolean VERBOSE = false;
37
38  private final AtomicInteger requestsInFlight = new AtomicInteger();
39
40  private OkHttpClient client;
41  private Response.Receiver receiver;
42  private int concurrencyLevel;
43  private int targetBacklog;
44
45  @Override public void prepare(final Benchmark benchmark) {
46    concurrencyLevel = benchmark.concurrencyLevel;
47    targetBacklog = benchmark.targetBacklog;
48
49    client = new OkHttpClient();
50    client.setProtocols(benchmark.protocols);
51    client.setDispatcher(new Dispatcher(new ThreadPoolExecutor(benchmark.concurrencyLevel,
52        benchmark.concurrencyLevel, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>())));
53
54    if (benchmark.tls) {
55      SSLContext sslContext = SslContextBuilder.localhost();
56      SSLSocketFactory socketFactory = sslContext.getSocketFactory();
57      HostnameVerifier hostnameVerifier = new HostnameVerifier() {
58        @Override public boolean verify(String s, SSLSession session) {
59          return true;
60        }
61      };
62      client.setSslSocketFactory(socketFactory);
63      client.setHostnameVerifier(hostnameVerifier);
64    }
65
66    receiver = new Response.Receiver() {
67      @Override public void onFailure(Failure failure) {
68        System.out.println("Failed: " + failure.exception());
69      }
70
71      @Override public boolean onResponse(Response response) throws IOException {
72        Response.Body body = response.body();
73        long total = SynchronousHttpClient.readAllAndClose(body.byteStream());
74        long finish = System.nanoTime();
75        if (VERBOSE) {
76          long start = (Long) response.request().tag();
77          System.out.printf("Transferred % 8d bytes in %4d ms%n",
78              total, TimeUnit.NANOSECONDS.toMillis(finish - start));
79        }
80        requestsInFlight.decrementAndGet();
81        return true;
82      }
83    };
84  }
85
86  @Override public void enqueue(URL url) throws Exception {
87    requestsInFlight.incrementAndGet();
88    client.enqueue(new Request.Builder().tag(System.nanoTime()).url(url).build(), receiver);
89  }
90
91  @Override public synchronized boolean acceptingJobs() {
92    return requestsInFlight.get() < (concurrencyLevel + targetBacklog);
93  }
94}
95