com.alexkli.jhb.Worker.java Source code

Java tutorial

Introduction

Here is the source code for com.alexkli.jhb.Worker.java

Source

/**************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *************************************************************************/

package com.alexkli.jhb;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketOption;
import java.net.SocketOptions;
import java.net.StandardSocketOptions;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.BlockingQueue;

import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;

/**
 * Workers take requests from the queue and run them over http.
 */
class Worker extends Thread {

    private final CloseableHttpClient httpClient;
    private final HttpClientContext context;
    private final BlockingQueue<QueueItem<HttpRequestBase>> queue;
    private final RunningAverage idleAvg = new RunningAverage();
    private final Jhb.Config config;

    public Worker(CloseableHttpClient httpClient, BlockingQueue<QueueItem<HttpRequestBase>> queue,
            Jhb.Config config) {
        this.httpClient = httpClient;
        this.context = HttpClientContext.create();
        this.queue = queue;
        this.config = config;
    }

    @Override
    public void run() {
        try {
            while (true) {
                long start = System.nanoTime();

                QueueItem<HttpRequestBase> item = queue.take();

                idleAvg.add(System.nanoTime() - start);

                if (item.isPoisonPill()) {
                    return;
                }

                HttpRequestBase request = item.getRequest();

                if ("java".equals(config.client)) {
                    System.setProperty("http.keepAlive", "false");

                    item.sent();

                    try {
                        HttpURLConnection http = (HttpURLConnection) new URL(request.getURI().toString())
                                .openConnection();
                        http.setConnectTimeout(5000);
                        http.setReadTimeout(5000);
                        int statusCode = http.getResponseCode();

                        consumeAndCloseStream(http.getInputStream());

                        if (statusCode == 200) {
                            item.done();
                        } else {
                            item.failed();
                        }
                    } catch (IOException e) {
                        System.err.println("Failed request: " + e.getMessage());
                        e.printStackTrace();
                        //                        System.exit(2);
                        item.failed();
                    }
                } else if ("ahc".equals(config.client)) {
                    try {
                        item.sent();

                        try (CloseableHttpResponse response = httpClient.execute(request, context)) {
                            int statusCode = response.getStatusLine().getStatusCode();
                            if (statusCode == 200) {
                                item.done();
                            } else {
                                item.failed();
                            }
                        }
                    } catch (IOException e) {
                        System.err.println("Failed request: " + e.getMessage());
                        item.failed();
                    }
                } else if ("fast".equals(config.client)) {
                    try {
                        URI uri = request.getURI();

                        item.sent();

                        InetAddress addr = InetAddress.getByName(uri.getHost());
                        Socket socket = new Socket(addr, uri.getPort());
                        PrintWriter out = new PrintWriter(socket.getOutputStream());
                        //                        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        // send an HTTP request to the web server
                        out.println("GET / HTTP/1.1");
                        out.append("Host: ").append(uri.getHost()).append(":").println(uri.getPort());
                        out.println("Connection: Close");
                        out.println();
                        out.flush();

                        // read the response
                        consumeAndCloseStream(socket.getInputStream());
                        //                        boolean loop = true;
                        //                        StringBuilder sb = new StringBuilder(8096);
                        //                        while (loop) {
                        //                            if (in.ready()) {
                        //                                int i = 0;
                        //                                while (i != -1) {
                        //                                    i = in.read();
                        //                                    sb.append((char) i);
                        //                                }
                        //                                loop = false;
                        //                            }
                        //                        }
                        item.done();
                        socket.close();

                    } catch (IOException e) {
                        e.printStackTrace();
                        item.failed();
                    }
                } else if ("nio".equals(config.client)) {
                    URI uri = request.getURI();

                    item.sent();

                    String requestBody = "GET / HTTP/1.1\n" + "Host: " + uri.getHost() + ":" + uri.getPort() + "\n"
                            + "Connection: Close\n\n";

                    try {
                        InetSocketAddress addr = new InetSocketAddress(uri.getHost(), uri.getPort());
                        SocketChannel channel = SocketChannel.open();
                        channel.socket().setSoTimeout(5000);
                        channel.connect(addr);

                        ByteBuffer msg = ByteBuffer.wrap(requestBody.getBytes());
                        channel.write(msg);
                        msg.clear();

                        ByteBuffer buf = ByteBuffer.allocate(1024);

                        int count;
                        while ((count = channel.read(buf)) != -1) {
                            buf.flip();

                            byte[] bytes = new byte[count];
                            buf.get(bytes);

                            buf.clear();
                        }
                        channel.close();

                        item.done();

                    } catch (IOException e) {
                        e.printStackTrace();
                        item.failed();
                    }
                }
            }
        } catch (InterruptedException e) {
            System.err.println("Worker thread [" + this.toString() + "] was interrupted: " + e.getMessage());
        }
    }

    private void consumeAndCloseStream(InputStream responseStream) throws IOException {
        try (InputStream ignored = responseStream) {
            IOUtils.copyLarge(responseStream, new OutputStream() {
                @Override
                public void write(int b) throws IOException {
                    // discard
                }

                @Override
                public void write(byte[] b) throws IOException {
                    // discard
                }

                @Override
                public void write(byte[] b, int off, int len) throws IOException {
                    // discard
                }
            });
        }
    }

    public double getAverageIdleNanos() {
        return idleAvg.getAverage();
    }
}