integration.HeavyLoad.java Source code

Java tutorial

Introduction

Here is the source code for integration.HeavyLoad.java

Source

/*
 * Copyright (C) 2009  Camptocamp
 *
 * This file is part of MapFish Print
 *
 * MapFish Print is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MapFish Print is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MapFish Print.  If not, see <http://www.gnu.org/licenses/>.
 */

package integration;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.log4j.*;
import org.pvalsecc.misc.FileUtilities;
import org.pvalsecc.misc.UnitUtilities;

import java.io.File;
import java.io.IOException;
import java.util.TreeSet;

/**
 * Simple program to test a tomcat print module under heavy load.
 */
public class HeavyLoad {
    private static final int NB_THREADS = 1;
    private static final int TIMEOUT = 3 * 60 * 1000;

    private static final String DEFAULT = "default";

    static {
        BasicConfigurator
                .configure(new ConsoleAppender(new PatternLayout("%d{HH:mm:ss.SSS} [%t] %-5p %30.30c - %m%n")));
        Logger.getRootLogger().setLevel(Level.INFO);

        //httpclient is a bit pesky about loading everything in memory...
        //disabling the warnings.
        Logger.getLogger(HttpMethodBase.class).setLevel(Level.ERROR);
    }

    public static final Logger LOGGER = Logger.getLogger(HeavyLoad.class);
    private static String url;
    private static HttpClient httpClient;
    private static String spec;
    private static final TreeSet<ServerStats> servers = new TreeSet<ServerStats>();

    public static void main(String[] args) throws IOException {
        url = args[0] + "/create.json";
        final String specFile = args[1];

        for (int i = 2; i < args.length; i++) {
            String server = args[i];
            servers.add(new ServerStats(server));
        }
        if (servers.isEmpty()) {
            servers.add(new ServerStats(DEFAULT));
        }

        MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
        final HttpConnectionManagerParams params = connectionManager.getParams();
        params.setSoTimeout(TIMEOUT);
        params.setConnectionTimeout(TIMEOUT);
        params.setDefaultMaxConnectionsPerHost(NB_THREADS);
        params.setMaxTotalConnections(NB_THREADS);

        httpClient = new HttpClient(connectionManager);

        spec = FileUtilities.readWholeTextFile(new File(specFile));

        Thread[] threads = new Thread[NB_THREADS];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Reader(), "reader-" + i);
            threads[i].start();
        }
        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
            }
        }
    }

    public static class Reader implements Runnable {

        public void run() {
            while (true) {
                doQuery();
            }
        }

        private static void doQuery() {

            final ServerStats server;
            synchronized (servers) {
                server = servers.first();
                servers.remove(server);
                server.addUsage();
                servers.add(server);
            }
            try {
                PostMethod method = new PostMethod(url);
                method.setRequestHeader("Connection", "close");
                method.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
                if (!server.server.equals(DEFAULT)) {
                    method.setRequestHeader("Cookie", "SRV=" + server.server + "; path=/");
                }
                method.setRequestEntity(new StringRequestEntity(spec, "application/json", "utf-8"));
                LOGGER.info("doing query... server=" + server.server);
                long start = System.currentTimeMillis();
                httpClient.executeMethod(method);
                if (method.getStatusCode() != 200) {
                    LOGGER.error("Invalid status code: " + method.getStatusCode());
                    System.exit(-1);
                }
                method.getResponseBody();
                final long duration = System.currentTimeMillis() - start;
                LOGGER.info("...query done in " + UnitUtilities.toElapsedTime(duration) + " server="
                        + server.updateStats(duration));
                method.releaseConnection();
            } catch (IOException e) {
                LOGGER.error("server=" + server, e);
                System.exit(-1);
            }
        }
    }

    private static class ServerStats implements Comparable<Object> {
        private final String server;
        private Integer curUsage = 0;
        private Integer totUsage = 0;
        private long totDuration = 0;

        public ServerStats(String server) {
            this.server = server;
        }

        public int compareTo(Object o) {
            if (!(o instanceof ServerStats)) {
                throw new RuntimeException();
            }
            final ServerStats other = (ServerStats) o;
            int thisVal = curUsage;
            int anotherVal = other.curUsage;
            int result = thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1);
            if (result == 0) {
                result = server.compareTo(other.server);
            }
            return result;
        }

        public synchronized String updateStats(long duration) {
            totUsage++;
            totDuration += duration;
            String result = toString();
            curUsage--;
            return result;
        }

        public synchronized String toString() {
            return String.format("%s avgTime=%s nbDone=%d curQ=%d", server,
                    totUsage > 0 ? UnitUtilities.toElapsedTime(totDuration / totUsage) : "null", totUsage,
                    curUsage);
        }

        public synchronized void addUsage() {
            curUsage++;
        }
    }
}