Clarify the ServerCallHandler API contract. (#8339)

- Focus the summary fragment
- Clarify that implementations don't just have access to "call" and
"headers" while running -- they in fact take ownership of these
arguments from the caller.
- Make explicit the caller's obligation to the returned Listener.
- Clarify that "{@code call} will be closed with an error" is actually
an obligation placed on the caller (who may be a user-defined
ServerInterceptor).
This commit is contained in:
John Cormie 2021-07-26 09:58:15 -07:00 committed by GitHub
parent 38cba5c8dd
commit ecac0da655
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 7 deletions

View File

@ -25,17 +25,26 @@ import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe @ThreadSafe
public interface ServerCallHandler<RequestT, ResponseT> { public interface ServerCallHandler<RequestT, ResponseT> {
/** /**
* Produce a non-{@code null} listener for the incoming call. Implementations are free to call * Starts asynchronous processing of an incoming call.
* methods on {@code call} before this method has returned.
* *
* <p>Since {@link Metadata} is not thread-safe, the caller must not access (read or write) {@code * <p>Callers of this method transfer their ownership of the non-thread-safe {@link ServerCall}
* headers} after this point. * and {@link Metadata} arguments to the {@link ServerCallHandler} implementation for processing.
* Ownership means that the implementation may invoke methods on {@code call} and {@code headers}
* while {@link #startCall} runs and at any time after it returns normally. On the other hand, if
* {@link #startCall} throws, ownership of {@code call} and {@code headers} reverts to the caller
* and the implementation loses the right to call methods on these objects (from some other
* thread, say).
* *
* <p>If the implementation throws an exception, {@code call} will be closed with an error. * <p>Ownership also includes the responsibility to eventually close {@code call}. In particular,
* Implementations must not throw an exception if they started processing that may use {@code * if {@link #startCall} throws an exception, the caller must handle it by closing {@code call}
* call} on another thread. * with an error. Since {@code call} can only be closed once, an implementation can report errors
* either to {@link ServerCall#close} for itself or by throwing an exception, but not both.
*
* <p>Returns a non-{@code null} listener for the incoming call. Callers of this method must
* arrange for events associated with {@code call} to be delivered there.
* *
* @param call object for responding to the remote client. * @param call object for responding to the remote client.
* @param headers request headers received from the client but open to modification by an owner
* @return listener for processing incoming request messages for {@code call} * @return listener for processing incoming request messages for {@code call}
*/ */
ServerCall.Listener<RequestT> startCall( ServerCall.Listener<RequestT> startCall(