package com.ning.pummel.cli;
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import org.skife.cli.Arguments;
import org.skife.cli.Command;
import org.skife.cli.Option;
import com.ning.pummel.Fist;
import com.ning.pummel.Poll;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@Command(name = {"benchmark", "go"}, description = "Go beat up a server")
public class Benchmark implements Callable<Void>
{
@Option(name = {"-c", "--concurrency"}, description = "concurrency -- how many requests to keep in flight at once")
public int concurrency = 10;
@Option(name = {"-m", "--max"}, description = "Maximum number of requests to execute")
public int maxRequests = -1;
@Option(name = {"-r", "--report"}, description = "report basic stats on stderr when finished")
public boolean report = false;
@Arguments(title="url file", description = "input file to pull urls from, otherwise will use stdin")
public File urlFile;
public Void call() throws Exception
{
LinkedBlockingQueue<String> urls = new LinkedBlockingQueue<String>();
final BufferedReader in;
if (urlFile != null) {
in = new BufferedReader(new InputStreamReader(new FileInputStream(urlFile)));
}
else {
in = new BufferedReader(new InputStreamReader(System.in));
}
for (String line = in.readLine(); line != null; line = in.readLine()) {
if (maxRequests >= 0) {
if (maxRequests == 0) {
break;
}
else if (maxRequests > 0) {
maxRequests--;
}
}
urls.add(line);
}
ExecutorService exec = Executors.newFixedThreadPool(concurrency);
ExecutorCompletionService<Poll> ecs = new ExecutorCompletionService<Poll>(exec);
long start = System.nanoTime();
for (String url : urls) {
ecs.submit(new Fist(url));
}
DescriptiveStatistics stats = new DescriptiveStatistics();
for (int i = urls.size(); i != 0; i--) {
Poll poll = ecs.take().get();
System.out.println(poll.getTime());
stats.addValue(poll.getTime());
}
long finish = System.nanoTime();
if (report) {
System.err.printf("time\t%d\n", TimeUnit.MILLISECONDS.convert(finish - start, TimeUnit.NANOSECONDS));
System.err.printf("n\t%d\n", stats.getN());
System.err.printf("max\t%f\n", stats.getMax());
System.err.printf("mean\t%f\n", stats.getMean());
System.err.printf("99.9%%\t%f\n", stats.getPercentile(99.9));
System.err.printf("99%%\t%f\n", stats.getPercentile(99));
System.err.printf("90%%\t%f\n", stats.getPercentile(90));
System.err.printf("80%%\t%f\n", stats.getPercentile(80));
System.err.printf("50%%\t%f\n", stats.getPercentile(50));
}
exec.shutdown();
return null;
}
}