Java tutorial
/******************************************************************************* * Copyright (c) 2011 Subgraph. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Subgraph - initial API and implementation ******************************************************************************/ package com.subgraph.vega.internal.crawler; import java.io.InterruptedIOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.http.client.methods.HttpUriRequest; import com.subgraph.vega.api.http.requests.IHttpRequestEngine; import com.subgraph.vega.api.http.requests.IHttpResponse; import com.subgraph.vega.api.http.requests.RequestEngineException; public class RequestConsumer implements Runnable { private final Logger logger = Logger.getLogger("crawler"); private final IHttpRequestEngine requestEngine; private final BlockingQueue<CrawlerTask> crawlerRequestQueue; private final BlockingQueue<CrawlerTask> crawlerResponseQueue; private final CountDownLatch latch; private volatile boolean stop; private final Object requestLock = new Object(); private volatile HttpUriRequest activeRequest = null; RequestConsumer(IHttpRequestEngine requestEngine, BlockingQueue<CrawlerTask> requestQueue, BlockingQueue<CrawlerTask> responseQueue, CountDownLatch latch) { this.requestEngine = requestEngine; this.crawlerRequestQueue = requestQueue; this.crawlerResponseQueue = responseQueue; this.latch = latch; } @Override public void run() { try { runLoop(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { latch.countDown(); } } void stop() { stop = true; synchronized (requestLock) { if (activeRequest != null) activeRequest.abort(); } } private void runLoop() throws InterruptedException { while (!stop) { CrawlerTask task = (CrawlerTask) crawlerRequestQueue.take(); if (task.isExitTask()) { // Put poison pill back in queue so every other RequestConsumer task will see it. crawlerRequestQueue.add(task); return; } logger.info("Retrieving: " + task.getRequest().getRequestLine().getUri()); if (!sendRequest(task)) { if (!stop && !task.causedException()) { logger.log(Level.WARNING, "No response was receiven for request to " + task.getRequest().getURI()); } } crawlerResponseQueue.put(task); } } private boolean sendRequest(CrawlerTask task) { try { activeRequest = task.getRequest(); final IHttpResponse response = requestEngine.sendRequest(task.getRequest()); task.setResponse(response); return response != null; } catch (RequestEngineException e) { if (e.getCause() instanceof InterruptedIOException) { stop = true; return false; } if (e.getMessage().contains("abort")) { return false; } task.setException(e); logger.log(Level.WARNING, e.getMessage()); return false; } finally { synchronized (requestLock) { activeRequest = null; } } } }