You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2009/01/13 20:24:25 UTC
svn commit: r734222 - in
/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor:
AbstractIOReactor.java AbstractMultiworkerIOReactor.java BaseIOReactor.java
ExceptionEvent.java
Author: olegk
Date: Tue Jan 13 11:24:17 2009
New Revision: 734222
URL: http://svn.apache.org/viewvc?rev=734222&view=rev
Log:
Javadoc updates
Modified:
httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java
Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java?rev=734222&r1=734221&r2=734222&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java Tue Jan 13 11:24:17 2009
@@ -93,6 +93,8 @@
/**
* Triggered when the key signals {@link SelectionKey#OP_ACCEPT} readiness.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param key the selection key.
*/
@@ -100,6 +102,8 @@
/**
* Triggered when the key signals {@link SelectionKey#OP_CONNECT} readiness.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param key the selection key.
*/
@@ -107,6 +111,8 @@
/**
* Triggered when the key signals {@link SelectionKey#OP_READ} readiness.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param key the selection key.
*/
@@ -114,21 +120,31 @@
/**
* Triggered when the key signals {@link SelectionKey#OP_WRITE} readiness.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param key the selection key.
*/
protected abstract void writable(SelectionKey key);
/**
- * Triggered to verify whether the key has not timed out.
+ * Triggered to verify whether the I/O session associated with the
+ * given selection key has not timed out.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param key the selection key.
- * @param current time as long value.
+ * @param now current time as long value.
*/
protected abstract void timeoutCheck(SelectionKey key, long now);
/**
- * Triggered to validate keys currently registered with the selector.
+ * Triggered to validate keys currently registered with the selector. This
+ * method is called after each I/O select loop.
+ * <p>
+ * Super-classes can implement this method to run validity checks on
+ * active sessions and include additional processing that needs to be
+ * executed after each I/O select loop.
*
* @param keys all selection keys registered with the selector.
*/
@@ -136,6 +152,8 @@
/**
* Triggered when new session has been created.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param key the selection key.
* @param session new I/O session.
@@ -144,6 +162,8 @@
/**
* Triggered when a session has been closed.
+ * <p>
+ * Super-classes can implement this method to react to the event.
*
* @param session closed I/O session.
*/
@@ -176,6 +196,28 @@
this.selector.wakeup();
}
+ /**
+ * Activates the I/O reactor. The I/O reactor will start reacting to
+ * I/O events and triggering notification methods.
+ * <p>
+ * This method will enter the infinite I/O select loop on
+ * the {@link Selector} instance associated with this I/O reactor.
+ * <p>
+ * The method will remain blocked unto the I/O reactor is shut down or the
+ * execution thread is interrupted.
+ *
+ * @see #acceptable(SelectionKey)
+ * @see #connectable(SelectionKey)
+ * @see #readable(SelectionKey)
+ * @see #writable(SelectionKey)
+ * @see #timeoutCheck(SelectionKey, long)
+ * @see #validate(Set)
+ * @see #sessionCreated(SelectionKey, IOSession)
+ * @see #sessionClosed(IOSession)
+ *
+ * @throws InterruptedIOException if the dispatch thread is interrupted.
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
protected void execute() throws InterruptedIOException, IOReactorException {
this.status = IOReactorStatus.ACTIVE;
Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java?rev=734222&r1=734221&r2=734222&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java Tue Jan 13 11:24:17 2009
@@ -47,6 +47,7 @@
import java.util.Set;
import java.util.concurrent.ThreadFactory;
+import org.apache.http.nio.params.NIOReactorPNames;
import org.apache.http.nio.params.NIOReactorParams;
import org.apache.http.nio.reactor.IOEventDispatch;
import org.apache.http.nio.reactor.IOReactor;
@@ -56,6 +57,44 @@
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
+/**
+ * Generic implementation of {@link IOReactor} that can run multiple
+ * {@link BaseIOReactor} instance in separate worker threads and distribute
+ * newly created I/O session equally across those I/O reactors for a more
+ * optimal resource utilization and a better I/O performance. Usually it is
+ * recommended to have one worker I/O reactor per physical CPU core.
+ * <p>
+ * <strong>Important note about exception handling</strong>
+ * <p>
+ * Protocol specific exceptions as well as those I/O exceptions thrown in the
+ * course of interaction with the session's channel are to be expected are to be
+ * dealt with by specific protocol handlers. These exceptions may result in
+ * termination of an individual session but should not affect the I/O reactor
+ * and all other active sessions. There are situations, however, when the I/O
+ * reactor itself encounters an internal problem such as an I/O exception in
+ * the underlying NIO classes or an unhandled runtime exception. Those types of
+ * exceptions are usually fatal and will cause the I/O reactor to shut down
+ * automatically.
+ * <p>
+ * There is a possibility to override this behavior and prevent I/O reactors
+ * from shutting down automatically in case of a runtime exception or an I/O
+ * exception in internal classes. This can be accomplished by providing a custom
+ * implementation of the {@link IOReactorExceptionHandler} interface.
+ * <p>
+ * If an I/O reactor is unable to automatically recover from an I/O or a runtime
+ * exception it will enter the shutdown mode. First off, it cancel all pending
+ * new session requests. Then it will attempt to close all active I/O sessions
+ * gracefully giving them some time to flush pending output data and terminate
+ * cleanly. Lastly, it will forcibly shut down those I/O sessions that still
+ * remain active after the grace period. This is a fairly complex process, where
+ * many things can fail at the same time and many different exceptions can be
+ * thrown in the course of the shutdown process. The I/O reactor will record all
+ * exceptions thrown during the shutdown process, including the original one
+ * that actually caused the shutdown in the first place, in an audit log. One
+ * can obtain the audit log using {@link #getAuditLog()}, examine exceptions
+ * thrown by the I/O reactor prior and in the course of the reactor shutdown
+ * and decide whether it is safe to restart the I/O reactor.
+ */
public abstract class AbstractMultiworkerIOReactor implements IOReactor {
protected volatile IOReactorStatus status;
@@ -77,6 +116,24 @@
private int currentWorker = 0;
+ /**
+ * Creates an instance of AbstractMultiworkerIOReactor.
+ * The following HTTP parameters affect the initialization:
+ * <p>
+ * The {@link NIOReactorPNames#SELECT_INTERVAL} parameter determines the
+ * time interval in milliseconds at which the I/O reactor wakes up to check
+ * for timed out sessions and session requests.
+ * <p>
+ * The {@link NIOReactorPNames#GRACE_PERIOD} parameter determines the grace
+ * period the I/O reactors are expected to block waiting for individual
+ * worker threads to terminate cleanly.
+ *
+ * @param workerCount number of worker I/O reactors.
+ * @param threadFactory the factory to create threads.
+ * Can be <code>null</code>.
+ * @param params HTTP parameters.
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
public AbstractMultiworkerIOReactor(
int workerCount,
final ThreadFactory threadFactory,
@@ -112,7 +169,13 @@
public IOReactorStatus getStatus() {
return this.status;
}
-
+
+ /**
+ * Returns the audit log containing exceptions thrown by the I/O reactor
+ * prior and in the course of the reactor shutdown.
+ *
+ * @return audit log.
+ */
public synchronized List<ExceptionEvent> getAuditLog() {
if (this.auditLog != null) {
return new ArrayList<ExceptionEvent>(this.auditLog);
@@ -121,6 +184,14 @@
}
}
+ /**
+ * Adds the given {@link Throwable} object with the given time stamp
+ * to the audit log.
+ *
+ * @param ex the exception thrown by the I/O reactor.
+ * @param timestamp the time stamp of the exception. Can be
+ * <code>null</code> in which case the current date / time will be used.
+ */
protected synchronized void addExceptionEvent(final Throwable ex, Date timestamp) {
if (ex == null) {
return;
@@ -134,18 +205,65 @@
this.auditLog.add(new ExceptionEvent(ex, timestamp));
}
+ /**
+ * Adds the given {@link Throwable} object to the audit log.
+ *
+ * @param ex the exception thrown by the I/O reactor.
+ */
protected void addExceptionEvent(final Throwable ex) {
addExceptionEvent(ex, null);
}
+ /**
+ * Sets exception handler for this I/O reactor.
+ *
+ * @param exceptionHandler the exception handler.
+ */
public void setExceptionHandler(final IOReactorExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
+ /**
+ * Triggered to process I/O events available in the selector.
+ * <p>
+ * Super-classes can implement this method to react to the event.
+ *
+ * @param count event count.
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
protected abstract void processEvents(int count) throws IOReactorException;
+ /**
+ * Triggered to cancel pending session requests.
+ * <p>
+ * Super-classes can implement this method to react to the event.
+ *
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
protected abstract void cancelRequests() throws IOReactorException;
+ /**
+ * Activates the main I/O reactor as well as all worker I/O reactors.
+ * The I/O main reactor will start reacting to I/O events and triggering
+ * notification methods. The worker I/O reactor in their turn will start
+ * reacting to I/O events and dispatch I/O event notifications to the given
+ * {@link IOEventDispatch} interface.
+ * <p>
+ * This method will enter the infinite I/O select loop on
+ * the {@link Selector} instance associated with this I/O reactor and used
+ * to manage creation of new I/O channels. Once a new I/O channel has been
+ * created the processing of I/O events on that channel will be delegated
+ * to one of the worker I/O reactors.
+ * <p>
+ * The method will remain blocked unto the I/O reactor is shut down or the
+ * execution thread is interrupted.
+ *
+ * @see #processEvents(int)
+ * @see #cancelRequests()
+ *
+ * @throws InterruptedIOException if the dispatch thread is interrupted.
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
public void execute(
final IOEventDispatch eventDispatch) throws InterruptedIOException, IOReactorException {
if (eventDispatch == null) {
Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java?rev=734222&r1=734221&r2=734222&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java Tue Jan 13 11:24:17 2009
@@ -40,10 +40,17 @@
import org.apache.http.nio.reactor.EventMask;
import org.apache.http.nio.reactor.IOEventDispatch;
+import org.apache.http.nio.reactor.IOReactor;
import org.apache.http.nio.reactor.IOReactorException;
import org.apache.http.nio.reactor.IOReactorExceptionHandler;
import org.apache.http.nio.reactor.IOSession;
+/**
+ * Default implementation of {@link AbstractIOReactor} that serves as a base
+ * for more advanced {@link IOReactor} implementations. This class adds
+ * support for the I/O event dispatching using {@link IOEventDispatch},
+ * management of buffering sessions, and session timeout handling.
+ */
public class BaseIOReactor extends AbstractIOReactor {
private final long timeoutCheckInterval;
@@ -54,6 +61,12 @@
private IOReactorExceptionHandler exceptionHandler = null;
private IOEventDispatch eventDispatch = null;
+ /**
+ * Creates new BaseIOReactor instance.
+ *
+ * @param selectTimeout the select timeout.
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
public BaseIOReactor(long selectTimeout) throws IOReactorException {
super(selectTimeout);
this.bufferingSessions = new HashSet<IOSession>();
@@ -61,6 +74,14 @@
this.lastTimeoutCheck = System.currentTimeMillis();
}
+ /**
+ * Activates the I/O reactor. The I/O reactor will start reacting to I/O
+ * events and dispatch I/O event notifications to the given
+ * {@link IOEventDispatch}.
+ *
+ * @throws InterruptedIOException if the dispatch thread is interrupted.
+ * @throws IOReactorException in case if a non-recoverable I/O error.
+ */
public void execute(
final IOEventDispatch eventDispatch) throws InterruptedIOException, IOReactorException {
if (eventDispatch == null) {
@@ -70,24 +91,53 @@
execute();
}
+ /**
+ * Sets exception handler for this I/O reactor.
+ *
+ * @param exceptionHandler the exception handler.
+ */
public void setExceptionHandler(IOReactorExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
+ /**
+ * Handles the given {@link RuntimeException}. This method delegates
+ * handling of the exception to the {@link IOReactorExceptionHandler},
+ * if available.
+ *
+ * @param ex the runtime exception.
+ */
protected void handleRuntimeException(final RuntimeException ex) {
if (this.exceptionHandler == null || !this.exceptionHandler.handle(ex)) {
throw ex;
}
}
+ /**
+ * This I/O reactor implementation does not react to the
+ * {@link SelectionKey#OP_ACCEPT} event.
+ * <p>
+ * Super-classes can override this method to react to the event.
+ */
@Override
protected void acceptable(final SelectionKey key) {
}
+ /**
+ * This I/O reactor implementation does not react to the
+ * {@link SelectionKey#OP_CONNECT} event.
+ * <p>
+ * Super-classes can override this method to react to the event.
+ */
@Override
protected void connectable(final SelectionKey key) {
}
+ /**
+ * Processes {@link SelectionKey#OP_READ} event on the given selection key.
+ * This method dispatches the event notification to the
+ * {@link IOEventDispatch#inputReady(IOSession)} method.
+ */
@Override
protected void readable(final SelectionKey key) {
SessionHandle handle = (SessionHandle) key.attachment();
@@ -107,6 +157,11 @@
}
}
+ /**
+ * Processes {@link SelectionKey#OP_WRITE} event on the given selection key.
+ * This method dispatches the event notification to the
+ * {@link IOEventDispatch#outputReady(IOSession)} method.
+ */
@Override
protected void writable(final SelectionKey key) {
SessionHandle handle = (SessionHandle) key.attachment();
@@ -123,6 +178,15 @@
}
}
+ /**
+ * Verifies whether any of the sessions associated with the given selection
+ * keys timed out by invoking the {@link #timeoutCheck(SelectionKey, long)}
+ * method.
+ * <p>
+ * This method will also invoke the
+ * {@link IOEventDispatch#inputReady(IOSession)} method on all sessions
+ * that have buffered input data.
+ */
@Override
protected void validate(final Set<SelectionKey> keys) {
long currentTime = System.currentTimeMillis();
@@ -169,6 +233,10 @@
}
}
+ /**
+ * Performs timeout check for the I/O session associated with the given
+ * selection key.
+ */
@Override
protected void timeoutCheck(final SelectionKey key, long now) {
Object attachment = key.attachment();
@@ -191,6 +259,10 @@
}
}
+ /**
+ * Processes newly created I/O session. This method dispatches the event
+ * notification to the {@link IOEventDispatch#connected(IOSession)} method.
+ */
@Override
protected void sessionCreated(final SelectionKey key, final IOSession session) {
SessionHandle handle = new SessionHandle(session);
@@ -216,6 +288,11 @@
}
}
+ /**
+ * Processes closed I/O session. This method dispatches the event
+ * notification to the {@link IOEventDispatch#disconnected(IOSession)}
+ * method.
+ */
@Override
protected void sessionClosed(final IOSession session) {
try {
Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java?rev=734222&r1=734221&r2=734222&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/ExceptionEvent.java Tue Jan 13 11:24:17 2009
@@ -1,7 +1,7 @@
/*
- * $HeadURL:$
- * $Revision:$
- * $Date:$
+ * $HeadURL$
+ * $Revision$
+ * $Date$
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -33,6 +33,9 @@
import java.util.Date;
+/**
+ * A {@link Throwable} instance along with a time stamp.
+ */
public class ExceptionEvent {
private final Throwable ex;