/*
* FetcherQueue.java
*
* Created on 10 January 2006, 05:49
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package org.owasp.webscarab.httpclient;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.owasp.webscarab.model.Request;
import org.owasp.webscarab.model.Response;
/**
*
* @author rdawes
*/
public class FetcherQueue {
private ConversationHandler _handler;
private Fetcher[] _fetchers;
private int _requestDelay;
private long _lastRequest = 0;
private List<Request> _requestQueue = new ArrayList<Request>();
private boolean _running = true;
private int _pending = 0;
/** Creates a new instance of FetcherQueue */
public FetcherQueue(String name, ConversationHandler handler, int threads, int requestDelay) {
_handler = handler;
_fetchers = new Fetcher[threads];
_requestDelay = requestDelay;
for (int i=0; i<threads; i++) {
_fetchers[i] = new Fetcher(name+"-"+i);
}
start();
}
public void stop() {
_running = false;
}
public void start() {
_running = true;
for (int i=0; i<_fetchers.length; i++) {
_fetchers[i].start();
}
}
public boolean isBusy() {
return _pending > 0 || getRequestsQueued() > 0;
}
public void submit(Request request) {
synchronized (_requestQueue) {
_requestQueue.add(request);
_requestQueue.notify();
}
}
public int getRequestsQueued() {
synchronized (_requestQueue) {
return _requestQueue.size();
}
}
public void clearRequestQueue() {
synchronized (_requestQueue) {
_requestQueue.clear();
}
}
private void responseReceived(Response response) {
_handler.responseReceived(response);
_pending--;
}
private void requestError(Request request, IOException ioe) {
_handler.requestError(request, ioe);
_pending--;
}
private Request getNextRequest() {
Request nextRequest = null;
synchronized (_requestQueue) {
while (_requestQueue.size() == 0) {
try {
_requestQueue.wait();
} catch (InterruptedException ie) {
// check again
}
}
nextRequest = _requestQueue.remove(0);
}
if (_requestDelay > 0) {
long currentTimeMillis = System.currentTimeMillis();
while (currentTimeMillis < _lastRequest + _requestDelay) {
try {
Thread.sleep(_lastRequest + _requestDelay - currentTimeMillis);
} catch (InterruptedException ie) {}
currentTimeMillis = System.currentTimeMillis();
}
_lastRequest = currentTimeMillis;
}
_pending++;
return nextRequest;
}
private class Fetcher extends Thread {
public Fetcher(String name) {
super(name);
setDaemon(true);
setPriority(Thread.MIN_PRIORITY);
}
public void run() {
HTTPClient client = HTTPClientFactory.getInstance().getHTTPClient();
while (_running) {
Request request = getNextRequest();
try {
Response response = client.fetchResponse(request);
response.flushContentStream();
responseReceived(response);
} catch (IOException ioe) {
requestError(request, ioe);
}
}
}
}
}