mirror of https://github.com/apache/jclouds.git
Issue 9: better javadoc
git-svn-id: http://jclouds.googlecode.com/svn/trunk@883 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
fd3c3841ee
commit
d9ff753ac4
|
@ -40,8 +40,8 @@ import com.google.inject.Inject;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?, ?>>
|
||||
extends BaseLifeCycle implements FutureCommandClient<O> {
|
||||
public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?, ?>> extends
|
||||
BaseLifeCycle implements FutureCommandClient<O> {
|
||||
private final FutureCommandConnectionPool<C, O> futureCommandConnectionPool;
|
||||
private final BlockingQueue<O> commandQueue;
|
||||
|
||||
|
@ -54,20 +54,27 @@ public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?,
|
|||
this.commandQueue = commandQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* we continue while the connection pool is active
|
||||
*/
|
||||
@Override
|
||||
protected boolean shouldDoWork() {
|
||||
return super.shouldDoWork()
|
||||
&& futureCommandConnectionPool.getStatus()
|
||||
.equals(Status.ACTIVE);
|
||||
return super.shouldDoWork() && futureCommandConnectionPool.getStatus().equals(Status.ACTIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* If the reason we are shutting down is due an exception, we set that exception on all pending
|
||||
* commands. Otherwise, we cancel the pending commands.
|
||||
*/
|
||||
@Override
|
||||
protected void doShutdown() {
|
||||
exception.compareAndSet(null, futureCommandConnectionPool
|
||||
.getException());
|
||||
exception.compareAndSet(null, futureCommandConnectionPool.getException());
|
||||
while (!commandQueue.isEmpty()) {
|
||||
FutureCommand<?, ?, ?> command = (FutureCommand<?, ?, ?>) commandQueue
|
||||
.remove();
|
||||
FutureCommand<?, ?, ?> command = (FutureCommand<?, ?, ?>) commandQueue.remove();
|
||||
if (command != null) {
|
||||
if (exception.get() != null)
|
||||
command.setException(exception.get());
|
||||
|
@ -79,6 +86,10 @@ public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?,
|
|||
|
||||
@Override
|
||||
protected void doWork() throws InterruptedException {
|
||||
takeACommandOffTheQueueAndInvokeIt();
|
||||
}
|
||||
|
||||
private void takeACommandOffTheQueueAndInvokeIt() throws InterruptedException {
|
||||
O command = commandQueue.poll(1, TimeUnit.SECONDS);
|
||||
if (command != null) {
|
||||
try {
|
||||
|
@ -90,36 +101,39 @@ public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an asynchronous operation that puts the <code>command</code> onto a queue. Later, it
|
||||
* will be processed via the {@link #invoke(FutureCommand) invoke} method.
|
||||
*/
|
||||
public void submit(O command) {
|
||||
exceptionIfNotActive();
|
||||
commandQueue.add(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke binds a command with a connection from the pool. This binding is called a
|
||||
* {@link FutureCommandConnectionHandle handle}. The handle will keep this binding until the
|
||||
* command's response is parsed or an exception is set on the Command object.
|
||||
*
|
||||
* @param command
|
||||
*/
|
||||
protected void invoke(O command) {
|
||||
exceptionIfNotActive();
|
||||
FutureCommandConnectionHandle<C, O> connectionHandle = null;
|
||||
try {
|
||||
connectionHandle = futureCommandConnectionPool.getHandle(command);
|
||||
} catch (InterruptedException e) {
|
||||
logger
|
||||
.warn(
|
||||
e,
|
||||
"Interrupted getting a connection for command %1$s; retrying",
|
||||
command);
|
||||
logger.warn(e, "Interrupted getting a connection for command %1$s; retrying", command);
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
} catch (TimeoutException e) {
|
||||
logger.warn(e,
|
||||
"Timeout getting a connection for command %1$s; retrying",
|
||||
command);
|
||||
logger.warn(e, "Timeout getting a connection for command %1$s; retrying", command);
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectionHandle == null) {
|
||||
logger.error(
|
||||
"Failed to obtain connection for command %1$s; retrying",
|
||||
command);
|
||||
logger.error("Failed to obtain connection for command %1$s; retrying", command);
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
}
|
||||
|
@ -131,10 +145,8 @@ public class FutureCommandConnectionPoolClient<C, O extends FutureCommand<?, ?,
|
|||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("FutureCommandConnectionPoolClient");
|
||||
sb.append("{status=").append(status);
|
||||
sb.append(", commandQueue=").append(
|
||||
(commandQueue != null) ? commandQueue.size() : 0);
|
||||
sb.append(", futureCommandConnectionPool=").append(
|
||||
futureCommandConnectionPool);
|
||||
sb.append(", commandQueue=").append((commandQueue != null) ? commandQueue.size() : 0);
|
||||
sb.append(", futureCommandConnectionPool=").append(futureCommandConnectionPool);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ import org.jclouds.http.commands.callables.xml.ParseSax;
|
|||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
* temporary factory until guice can do multi-type assisted inject
|
||||
* @see <a href="http://code.google.com/p/google-guice/issues/detail?id=346" />
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
|
|
@ -46,8 +46,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
|||
protected volatile Status status;
|
||||
protected AtomicReference<Exception> exception = new AtomicReference<Exception>();
|
||||
|
||||
public BaseLifeCycle(ExecutorService executor,
|
||||
BaseLifeCycle... dependencies) {
|
||||
public BaseLifeCycle(ExecutorService executor, BaseLifeCycle... dependencies) {
|
||||
this.executor = executor;
|
||||
this.dependencies = dependencies;
|
||||
this.statusLock = new Object();
|
||||
|
@ -77,6 +76,10 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
|||
|
||||
protected abstract void doShutdown();
|
||||
|
||||
/**
|
||||
* @return false if any dependencies are inactive, or we are inactive, or we have a global
|
||||
* exception.
|
||||
*/
|
||||
protected boolean shouldDoWork() {
|
||||
try {
|
||||
exceptionIfDepedenciesNotActive();
|
||||
|
@ -116,8 +119,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
|||
for (BaseLifeCycle dependency : dependencies) {
|
||||
if (dependency.status.compareTo(Status.ACTIVE) != 0) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Illegal state: %1$s for component: %2$s",
|
||||
dependency.status, dependency));
|
||||
"Illegal state: %1$s for component: %2$s", dependency.status, dependency));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,8 +132,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
|||
awaitStatus(Status.SHUT_DOWN, timeout);
|
||||
}
|
||||
|
||||
protected void awaitStatus(Status intended, long timeout)
|
||||
throws InterruptedException {
|
||||
protected void awaitStatus(Status intended, long timeout) throws InterruptedException {
|
||||
synchronized (this.statusLock) {
|
||||
long deadline = System.currentTimeMillis() + timeout;
|
||||
long remaining = timeout;
|
||||
|
@ -167,8 +168,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle {
|
|||
|
||||
protected void exceptionIfNotActive() {
|
||||
if (!status.equals(Status.ACTIVE))
|
||||
throw new IllegalStateException(String.format("not active: %1$s",
|
||||
this));
|
||||
throw new IllegalStateException(String.format("not active: %1$s", this));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
* This will close objects in the reverse order that they were added.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
|
|
@ -48,7 +48,9 @@ import com.google.inject.spi.TypeEncounter;
|
|||
import com.google.inject.spi.TypeListener;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
* This associates java lifecycle annotations with guice hooks. For example, we invoke
|
||||
* {@link PostConstruct} after injection, and Associate {@link PostDestroy} with a global
|
||||
* {@link Closer} object.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -69,8 +71,7 @@ public class LifeCycleModule extends AbstractModule {
|
|||
|
||||
protected void bindPostInjectionInvoke(final Closer closer) {
|
||||
bindListener(any(), new TypeListener() {
|
||||
public <I> void hear(TypeLiteral<I> injectableType,
|
||||
TypeEncounter<I> encounter) {
|
||||
public <I> void hear(TypeLiteral<I> injectableType, TypeEncounter<I> encounter) {
|
||||
Set<Method> methods = new HashSet<Method>();
|
||||
Class<? super I> type = injectableType.getRawType();
|
||||
while (type != null) {
|
||||
|
@ -78,27 +79,14 @@ public class LifeCycleModule extends AbstractModule {
|
|||
type = type.getSuperclass();
|
||||
}
|
||||
for (final Method method : methods) {
|
||||
PostConstruct postConstruct = method
|
||||
.getAnnotation(PostConstruct.class);
|
||||
if (postConstruct != null) {
|
||||
encounter.register(new InjectionListener<I>() {
|
||||
public void afterInjection(I injectee) {
|
||||
try {
|
||||
method.invoke(injectee);
|
||||
} catch (InvocationTargetException ie) {
|
||||
Throwable e = ie.getTargetException();
|
||||
throw new ProvisionException(
|
||||
e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ProvisionException(
|
||||
e.getMessage(), e);
|
||||
invokePostConstructMethodAfterInjection(encounter, method);
|
||||
associatePreDestroyWithCloser(closer, encounter, method);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PreDestroy preDestroy = method
|
||||
.getAnnotation(PreDestroy.class);
|
||||
private <I> void associatePreDestroyWithCloser(final Closer closer,
|
||||
TypeEncounter<I> encounter, final Method method) {
|
||||
PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
|
||||
if (preDestroy != null) {
|
||||
encounter.register(new InjectionListener<I>() {
|
||||
public void afterInjection(final I injectee) {
|
||||
|
@ -107,13 +95,10 @@ public class LifeCycleModule extends AbstractModule {
|
|||
try {
|
||||
method.invoke(injectee);
|
||||
} catch (InvocationTargetException ie) {
|
||||
Throwable e = ie
|
||||
.getTargetException();
|
||||
throw new IOException(e
|
||||
.getMessage());
|
||||
Throwable e = ie.getTargetException();
|
||||
throw new IOException(e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IOException(e
|
||||
.getMessage());
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -122,6 +107,24 @@ public class LifeCycleModule extends AbstractModule {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
private <I> void invokePostConstructMethodAfterInjection(TypeEncounter<I> encounter,
|
||||
final Method method) {
|
||||
PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
|
||||
if (postConstruct != null) {
|
||||
encounter.register(new InjectionListener<I>() {
|
||||
public void afterInjection(I injectee) {
|
||||
try {
|
||||
method.invoke(injectee);
|
||||
} catch (InvocationTargetException ie) {
|
||||
Throwable e = ie.getTargetException();
|
||||
throw new ProvisionException(e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ProvisionException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue