From ecac0da655d16ab7c4852f9ff88eafa638fc5a69 Mon Sep 17 00:00:00 2001 From: John Cormie Date: Mon, 26 Jul 2021 09:58:15 -0700 Subject: [PATCH] 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). --- .../main/java/io/grpc/ServerCallHandler.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/io/grpc/ServerCallHandler.java b/api/src/main/java/io/grpc/ServerCallHandler.java index 13d0b4128f0..fdfa9997957 100644 --- a/api/src/main/java/io/grpc/ServerCallHandler.java +++ b/api/src/main/java/io/grpc/ServerCallHandler.java @@ -25,17 +25,26 @@ @ThreadSafe public interface ServerCallHandler { /** - * Produce a non-{@code null} listener for the incoming call. Implementations are free to call - * methods on {@code call} before this method has returned. + * Starts asynchronous processing of an incoming call. * - *

Since {@link Metadata} is not thread-safe, the caller must not access (read or write) {@code - * headers} after this point. + *

Callers of this method transfer their ownership of the non-thread-safe {@link ServerCall} + * 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). * - *

If the implementation throws an exception, {@code call} will be closed with an error. - * Implementations must not throw an exception if they started processing that may use {@code - * call} on another thread. + *

Ownership also includes the responsibility to eventually close {@code call}. In particular, + * if {@link #startCall} throws an exception, the caller must handle it by closing {@code call} + * 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. + * + *

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 headers request headers received from the client but open to modification by an owner * @return listener for processing incoming request messages for {@code call} */ ServerCall.Listener startCall(