Javadoc improvements, especially to Context

This commit is contained in:
Eric Anderson 2017-05-15 10:12:44 -07:00 committed by GitHub
parent 17b74c1452
commit eb6acfe186
9 changed files with 91 additions and 54 deletions

View File

@ -60,11 +60,11 @@ import java.util.logging.Logger;
* *
* <pre> * <pre>
* Context withCredential = Context.current().withValue(CRED_KEY, cred); * Context withCredential = Context.current().withValue(CRED_KEY, cred);
* executorService.execute(withCredential.wrap(new Runnable() { * withCredential.run(new Runnable() {
* public void run() { * public void run() {
* readUserRecords(userId, CRED_KEY.get()); * readUserRecords(userId, CRED_KEY.get());
* } * }
* })); * });
* </pre> * </pre>
* *
* <p>Contexts are also used to represent a scoped unit of work. When the unit of work is done the * <p>Contexts are also used to represent a scoped unit of work. When the unit of work is done the
@ -78,7 +78,7 @@ import java.util.logging.Logger;
* <pre> * <pre>
* CancellableContext withCancellation = Context.current().withCancellation(); * CancellableContext withCancellation = Context.current().withCancellation();
* try { * try {
* executorService.execute(withCancellation.wrap(new Runnable() { * withCancellation.run(new Runnable() {
* public void run() { * public void run() {
* while (waitingForData() &amp;&amp; !Context.current().isCancelled()) {} * while (waitingForData() &amp;&amp; !Context.current().isCancelled()) {}
* } * }
@ -95,12 +95,13 @@ import java.util.logging.Logger;
* *
* <p>Notes and cautions on use: * <p>Notes and cautions on use:
* <ul> * <ul>
* <li>Every {@code attach()} should have a {@code detach()} in the same method. And every
* CancellableContext should be cancelled at some point. Breaking these rules may lead to memory
* leaks.
* <li>While Context objects are immutable they do not place such a restriction on the state * <li>While Context objects are immutable they do not place such a restriction on the state
* they store.</li> * they store.</li>
* <li>Context is not intended for passing optional parameters to an API and developers should * <li>Context is not intended for passing optional parameters to an API and developers should
* take care to avoid excessive dependence on context when designing an API.</li> * take care to avoid excessive dependence on context when designing an API.</li>
* <li>If Context is being used in an environment that needs to support class unloading it is the
* responsibility of the application to ensure that all contexts are properly cancelled.</li>
* </ul> * </ul>
*/ */
public class Context { public class Context {
@ -228,15 +229,16 @@ public class Context {
/** /**
* Create a new context which is independently cancellable and also cascades cancellation from * Create a new context which is independently cancellable and also cascades cancellation from
* its parent. Callers should ensure that either {@link CancellableContext#cancel(Throwable)} * its parent. Callers <em>must</em> ensure that either {@link
* or {@link CancellableContext#detachAndCancel(Context, Throwable)} are called to notify * CancellableContext#cancel(Throwable)} or {@link CancellableContext#detachAndCancel(Context,
* listeners and release the resources associated with them. * Throwable)} are called at a later point, in order to allow this context to be garbage
* collected.
* *
* <p>Sample usage: * <p>Sample usage:
* <pre> * <pre>
* Context.CancellableContext withCancellation = Context.current().withCancellation(); * Context.CancellableContext withCancellation = Context.current().withCancellation();
* try { * try {
* executorService.execute(withCancellation.wrap(new Runnable() { * withCancellation.run(new Runnable() {
* public void run() { * public void run() {
* Context current = Context.current(); * Context current = Context.current();
* while (!current.isCancelled()) { * while (!current.isCancelled()) {
@ -244,9 +246,8 @@ public class Context {
* } * }
* } * }
* }); * });
* doSomethingRelatedWork(); * } finally {
* } catch (Throwable t) { * withCancellation.cancel(null);
* withCancellation.cancel(t);
* } * }
* </pre> * </pre>
*/ */
@ -257,20 +258,26 @@ public class Context {
/** /**
* Create a new context which will cancel itself after the given {@code duration} from now. * Create a new context which will cancel itself after the given {@code duration} from now.
* The returned context will cascade cancellation of its parent. Callers may explicitly cancel * The returned context will cascade cancellation of its parent. Callers may explicitly cancel
* the returned context prior to the deadline just as for {@link #withCancellation()}, * the returned context prior to the deadline just as for {@link #withCancellation()}. If the unit
* of work completes before the deadline, the context should be explicitly cancelled to allow
* it to be garbage collected.
* *
* <p>Sample usage: * <p>Sample usage:
* <pre> * <pre>
* Context.CancellableContext withDeadline = Context.current().withDeadlineAfter(5, * Context.CancellableContext withDeadline = Context.current()
* TimeUnit.SECONDS, scheduler); * .withDeadlineAfter(5, TimeUnit.SECONDS, scheduler);
* executorService.execute(withDeadline.wrap(new Runnable() { * try {
* public void run() { * withDeadline.run(new Runnable() {
* Context current = Context.current(); * public void run() {
* while (!current.isCancelled()) { * Context current = Context.current();
* keepWorking(); * while (!current.isCancelled()) {
* keepWorking();
* }
* } * }
* } * });
* }); * } finally {
* withDeadline.cancel(null);
* }
* </pre> * </pre>
*/ */
public CancellableContext withDeadlineAfter(long duration, TimeUnit unit, public CancellableContext withDeadlineAfter(long duration, TimeUnit unit,
@ -281,20 +288,26 @@ public class Context {
/** /**
* Create a new context which will cancel itself at the given {@link Deadline}. * Create a new context which will cancel itself at the given {@link Deadline}.
* The returned context will cascade cancellation of its parent. Callers may explicitly cancel * The returned context will cascade cancellation of its parent. Callers may explicitly cancel
* the returned context prior to the deadline just as for {@link #withCancellation()}, * the returned context prior to the deadline just as for {@link #withCancellation()}. If the unit
* of work completes before the deadline, the context should be explicitly cancelled to allow
* it to be garbage collected.
* *
* <p>Sample usage: * <p>Sample usage:
* <pre> * <pre>
* Context.CancellableContext withDeadline = Context.current() * Context.CancellableContext withDeadline = Context.current()
* .withDeadline(someReceivedDeadline); * .withDeadline(someReceivedDeadline, scheduler);
* executorService.execute(withDeadline.wrap(new Runnable() { * try {
* public void run() { * withDeadline.run(new Runnable() {
* Context current = Context.current(); * public void run() {
* while (!current.isCancelled()) { * Context current = Context.current();
* keepWorking(); * while (!current.isCancelled() &amp;&amp; moreWorkToDo()) {
* keepWorking();
* }
* } * }
* } * });
* }); * } finally {
* withDeadline.cancel(null);
* }
* </pre> * </pre>
*/ */
public CancellableContext withDeadline(Deadline deadline, public CancellableContext withDeadline(Deadline deadline,
@ -310,11 +323,11 @@ public class Context {
* *
<pre> <pre>
* Context withCredential = Context.current().withValue(CRED_KEY, cred); * Context withCredential = Context.current().withValue(CRED_KEY, cred);
* executorService.execute(withCredential.wrap(new Runnable() { * withCredential.run(new Runnable() {
* public void run() { * public void run() {
* readUserRecords(userId, CRED_KEY.get()); * readUserRecords(userId, CRED_KEY.get());
* } * }
* })); * });
* </pre> * </pre>
* *
*/ */
@ -366,10 +379,19 @@ public class Context {
* previously current context is returned. It is allowed to attach contexts where {@link * previously current context is returned. It is allowed to attach contexts where {@link
* #isCancelled()} is {@code true}. * #isCancelled()} is {@code true}.
* *
* <p>Instead of using {@link #attach()} & {@link #detach(Context)} most use-cases are better * <p>Instead of using {@code attach()} and {@link #detach(Context)} most use-cases are better
* served by using the {@link #run(Runnable)} or {@link #call(java.util.concurrent.Callable)} to * served by using the {@link #run(Runnable)} or {@link #call(java.util.concurrent.Callable)} to
* execute work immediately within a context's scope. If work needs to be done in other threads it * execute work immediately within a context's scope. If work needs to be done in other threads it
* is recommended to use the 'wrap' methods or to use a propagating executor. * is recommended to use the 'wrap' methods or to use a propagating executor.
*
* <p>All calls to {@code attach()} should have a corresponding {@link #detach(Context)} within
* the same method:
* <pre>{@code Context previous = someContext.attach();
* try {
* // Do work
* } finally {
* someContext.detach(previous);
* }}</pre>
*/ */
public Context attach() { public Context attach() {
Context previous = current(); Context previous = current();
@ -378,8 +400,7 @@ public class Context {
} }
/** /**
* Detach the current context and attach the provided replacement which should be the context of * Reverse an {@code attach()}, restoring the previous context and exiting the current scope.
* the outer scope, thus exit the current scope.
* *
* <p>This context should be the same context that was previously {@link #attach attached}. The * <p>This context should be the same context that was previously {@link #attach attached}. The
* provided replacement should be what was returned by the same {@link #attach attach()} call. If * provided replacement should be what was returned by the same {@link #attach attach()} call. If
@ -649,7 +670,9 @@ public class Context {
/** /**
* A context which inherits cancellation from its parent but which can also be independently * A context which inherits cancellation from its parent but which can also be independently
* cancelled and which will propagate cancellation to its descendants. * cancelled and which will propagate cancellation to its descendants. To avoid leaking memory,
* every CancellableContext must have a defined lifetime, after which it is guaranteed to be
* cancelled.
*/ */
public static final class CancellableContext extends Context { public static final class CancellableContext extends Context {

View File

@ -36,7 +36,14 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* An absolute deadline in system time. * An absolute point in time, generally for tracking when a task should be completed. A deadline is
* immutable except for the passage of time causing it to expire.
*
* <p>Many systems use timeouts, which are relative to the start of the operation. However, being
* relative causes them to be poorly suited for managing higher-level tasks where there are many
* components and sub-operations that may not know the time of the initial "start of the operation."
* However, a timeout can be converted to a {@code Deadline} at the start of the operation and then
* passed to the various components unambiguously.
*/ */
public final class Deadline implements Comparable<Deadline> { public final class Deadline implements Comparable<Deadline> {
private static final SystemTicker SYSTEM_TICKER = new SystemTicker(); private static final SystemTicker SYSTEM_TICKER = new SystemTicker();

View File

@ -34,15 +34,16 @@ package io.grpc;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
/** /**
* A Channel provides an abstraction over the transport layer that is designed to be consumed * A virtual connection to a conceptual endpoint, to perform RPCs. A channel is free to have zero or
* by stub implementations. Channel and its associated types {@link ClientCall} and * many actual connections to the endpoint based on configuration, load, etc. A channel is also free
* {@link ClientCall.Listener} exchange parsed request and response objects whereas the * to determine which actual endpoints to use and may change it every RPC, permitting client-side
* transport layer only works with serialized data. * load balancing. Applications are generally expected to use stubs instead of calling this class
* directly.
* *
* <p>Applications can add common cross-cutting behaviors to stubs by decorating Channel * <p>Applications can add common cross-cutting behaviors to stubs by decorating Channel
* implementations using {@link ClientInterceptor}. It is expected that most application * implementations using {@link ClientInterceptor}. It is expected that most application
* code will not use this class directly but rather work with stubs that have been bound to a * code will not use this class directly but rather work with stubs that have been bound to a
* Channel that was decorated during application initialization, * Channel that was decorated during application initialization.
*/ */
@ThreadSafe @ThreadSafe
public abstract class Channel { public abstract class Channel {

View File

@ -236,7 +236,8 @@ public abstract class ClientCall<ReqT, RespT> {
* just a suggestion and the application is free to ignore it, however doing so may * just a suggestion and the application is free to ignore it, however doing so may
* result in excessive buffering within the call. * result in excessive buffering within the call.
* *
* <p>This implementation always returns {@code true}. * <p>This abstract class's implementation always returns {@code true}. Implementations generally
* override the method.
*/ */
public boolean isReady() { public boolean isReady() {
return true; return true;

View File

@ -198,8 +198,6 @@ public abstract class LoadBalancer {
/** /**
* The main balancing logic. It <strong>must be thread-safe</strong>. Typically it should only * The main balancing logic. It <strong>must be thread-safe</strong>. Typically it should only
* synchronize on its own state, and avoid synchronizing with the LoadBalancer's state. * synchronize on its own state, and avoid synchronizing with the LoadBalancer's state.
*
* <p>Note: Implementations should override exactly one {@code pickSubchannel}.
*/ */
@ThreadSafe @ThreadSafe
public abstract static class SubchannelPicker { public abstract static class SubchannelPicker {

View File

@ -129,7 +129,9 @@ public abstract class ServerBuilder<T extends ServerBuilder<T>> {
/** /**
* Sets a fallback handler registry that will be looked up in if a method is not found in the * Sets a fallback handler registry that will be looked up in if a method is not found in the
* primary registry. * primary registry. The primary registry (configured via {@code addService()}) is faster but
* immutable. The fallback registry is more flexible and allows implementations to mutate over
* time and load services on-demand.
* *
* @return this * @return this
* @since 1.0.0 * @since 1.0.0

View File

@ -39,8 +39,7 @@ package io.grpc;
* <p>Multiple filters maybe registered to a server, in which case the output of a filter is the * <p>Multiple filters maybe registered to a server, in which case the output of a filter is the
* input of the next filter. For example, what returned by {@link #transportReady} of a filter is * input of the next filter. For example, what returned by {@link #transportReady} of a filter is
* passed to the same method of the next filter, and the last filter's return value is the effective * passed to the same method of the next filter, and the last filter's return value is the effective
* transport attributes. A filter should modify the passed-in attributes instead of creating one * transport attributes.
* from scratch.
* *
* <p>{@link Grpc} defines commonly used attributes. * <p>{@link Grpc} defines commonly used attributes.
*/ */

View File

@ -43,16 +43,20 @@ import io.grpc.ExperimentalApi;
import io.grpc.ManagedChannelBuilder; import io.grpc.ManagedChannelBuilder;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
/** /**
* Common base type for stub implementations. * Common base type for stub implementations. Stub configuration is immutable; changing the
* configuration returns a new stub with updated configuration. Changing the configuration is cheap
* and may be done before every RPC, such as would be common when using {@link #withDeadlineAfter}.
* *
* <p>This is the base class of the stub classes from the generated code. It allows for * <p>Configuration is stored in {@link CallOptions} and is passed to the {@link Channel} when
* reconfiguration, e.g., attaching interceptors to the stub. * performing an RPC.
* *
* @since 1.0.0 * @since 1.0.0
* @param <S> the concrete type of this stub. * @param <S> the concrete type of this stub.
*/ */
@ThreadSafe
public abstract class AbstractStub<S extends AbstractStub<S>> { public abstract class AbstractStub<S extends AbstractStub<S>> {
private final Channel channel; private final Channel channel;
private final CallOptions callOptions; private final CallOptions callOptions;

View File

@ -54,8 +54,10 @@ import io.grpc.ExperimentalApi;
public abstract class CallStreamObserver<V> implements StreamObserver<V> { public abstract class CallStreamObserver<V> implements StreamObserver<V> {
/** /**
* If {@code true} indicates that a call to {@link #onNext(Object)} will not require the entire * If {@code true}, indicates that the observer is capable of sending additional messages
* message to be buffered before it is sent to the peer. * without requiring excessive buffering internally. This value is just a suggestion and the
* application is free to ignore it, however doing so may result in excessive buffering within the
* observer.
*/ */
public abstract boolean isReady(); public abstract boolean isReady();