1 /* 2 * Copyright 2014 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc; 18 19 import javax.annotation.Nullable; 20 21 /** 22 * An instance of a call to a remote method. A call will send zero or more 23 * request messages to the server and receive zero or more response messages back. 24 * 25 * <p>Instances are created 26 * by a {@link Channel} and used by stubs to invoke their remote behavior. 27 * 28 * <p>More advanced usages may consume this interface directly as opposed to using a stub. Common 29 * reasons for doing so would be the need to interact with flow-control or when acting as a generic 30 * proxy for arbitrary operations. 31 * 32 * <p>{@link #start} must be called prior to calling any other methods, with the exception of 33 * {@link #cancel}. Whereas {@link #cancel} must not be followed by any other methods, 34 * but can be called more than once, while only the first one has effect. 35 * 36 * <p>No generic method for determining message receipt or providing acknowledgement is provided. 37 * Applications are expected to utilize normal payload messages for such signals, as a response 38 * naturally acknowledges its request. 39 * 40 * <p>Methods are guaranteed to be non-blocking. Not thread-safe except for {@link #request}, which 41 * may be called from any thread. 42 * 43 * <p>There is no interaction between the states on the {@link Listener Listener} and {@link 44 * ClientCall}, i.e., if {@link Listener#onClose Listener.onClose()} is called, it has no bearing on 45 * the permitted operations on {@code ClientCall} (but it may impact whether they do anything). 46 * 47 * <p>There is a race between {@link #cancel} and the completion/failure of the RPC in other ways. 48 * If {@link #cancel} won the race, {@link Listener#onClose Listener.onClose()} is called with 49 * {@link Status#CANCELLED CANCELLED}. Otherwise, {@link Listener#onClose Listener.onClose()} is 50 * called with whatever status the RPC was finished. We ensure that at most one is called. 51 * 52 * <h3>Usage examples</h3> 53 * <h4>Simple Unary (1 request, 1 response) RPC</h4> 54 * <pre> 55 * call = channel.newCall(unaryMethod, callOptions); 56 * call.start(listener, headers); 57 * call.sendMessage(message); 58 * call.halfClose(); 59 * call.request(1); 60 * // wait for listener.onMessage() 61 * </pre> 62 * 63 * <h4>Flow-control in Streaming RPC</h4> 64 * 65 * <p>The following snippet demonstrates a bi-directional streaming case, where the client sends 66 * requests produced by a fictional <code>makeNextRequest()</code> in a flow-control-compliant 67 * manner, and notifies gRPC library to receive additional response after one is consumed by 68 * a fictional <code>processResponse()</code>. 69 * 70 * <p><pre> 71 * call = channel.newCall(bidiStreamingMethod, callOptions); 72 * listener = new ClientCall.Listener<FooResponse>() { 73 * @Override 74 * public void onMessage(FooResponse response) { 75 * processResponse(response); 76 * // Notify gRPC to receive one additional response. 77 * call.request(1); 78 * } 79 * 80 * @Override 81 * public void onReady() { 82 * while (call.isReady()) { 83 * FooRequest nextRequest = makeNextRequest(); 84 * if (nextRequest == null) { // No more requests to send 85 * call.halfClose(); 86 * return; 87 * } 88 * call.sendMessage(nextRequest); 89 * } 90 * } 91 * } 92 * call.start(listener, headers); 93 * // Notify gRPC to receive one response. Without this line, onMessage() would never be called. 94 * call.request(1); 95 * </pre> 96 * 97 * <p>DO NOT MOCK: Use InProcessServerBuilder and make a test server instead. 98 * 99 * @param <ReqT> type of message sent one or more times to the server. 100 * @param <RespT> type of message received one or more times from the server. 101 */ 102 public abstract class ClientCall<ReqT, RespT> { 103 /** 104 * Callbacks for receiving metadata, response messages and completion status from the server. 105 * 106 * <p>Implementations are free to block for extended periods of time. Implementations are not 107 * required to be thread-safe, but they must not be thread-hostile. The caller is free to call 108 * an instance from multiple threads, but only one call simultaneously. A single thread may 109 * interleave calls to multiple instances, so implementations using ThreadLocals must be careful 110 * to avoid leaking inappropriate state (e.g., clearing the ThreadLocal before returning). 111 * 112 * @param <T> type of message received. 113 */ 114 public abstract static class Listener<T> { 115 116 /** 117 * The response headers have been received. Headers always precede messages. 118 * 119 * <p>Since {@link Metadata} is not thread-safe, the caller must not access (read or write) 120 * {@code headers} after this point. 121 * 122 * @param headers containing metadata sent by the server at the start of the response. 123 */ onHeaders(Metadata headers)124 public void onHeaders(Metadata headers) {} 125 126 /** 127 * A response message has been received. May be called zero or more times depending on whether 128 * the call response is empty, a single message or a stream of messages. 129 * 130 * @param message returned by the server 131 */ onMessage(T message)132 public void onMessage(T message) {} 133 134 /** 135 * The ClientCall has been closed. Any additional calls to the {@code ClientCall} will not be 136 * processed by the server. No further receiving will occur and no further notifications will be 137 * made. 138 * 139 * <p>Since {@link Metadata} is not thread-safe, the caller must not access (read or write) 140 * {@code trailers} after this point. 141 * 142 * <p>If {@code status} returns false for {@link Status#isOk()}, then the call failed. 143 * An additional block of trailer metadata may be received at the end of the call from the 144 * server. An empty {@link Metadata} object is passed if no trailers are received. 145 * 146 * <p>This method should not throw. If this method throws, there is no way to be notified of the 147 * exception. Implementations should therefore be careful of exceptions which can accidentally 148 * leak resources. 149 * 150 * @param status the result of the remote call. 151 * @param trailers metadata provided at call completion. 152 */ onClose(Status status, Metadata trailers)153 public void onClose(Status status, Metadata trailers) {} 154 155 /** 156 * This indicates that the ClientCall may now be capable of sending additional messages (via 157 * {@link #sendMessage}) without requiring excessive buffering internally. This event is 158 * just a suggestion and the application is free to ignore it, however doing so may 159 * result in excessive buffering within the ClientCall. 160 * 161 * <p>Because there is a processing delay to deliver this notification, it is possible for 162 * concurrent writes to cause {@code isReady() == false} within this callback. Handle "spurious" 163 * notifications by checking {@code isReady()}'s current value instead of assuming it is now 164 * {@code true}. If {@code isReady() == false} the normal expectations apply, so there would be 165 * <em>another</em> {@code onReady()} callback. 166 * 167 * <p>If the type of a call is either {@link MethodDescriptor.MethodType#UNARY} or 168 * {@link MethodDescriptor.MethodType#SERVER_STREAMING}, this callback may not be fired. Calls 169 * that send exactly one message should not await this callback. 170 */ onReady()171 public void onReady() {} 172 } 173 174 /** 175 * Start a call, using {@code responseListener} for processing response messages. 176 * 177 * <p>It must be called prior to any other method on this class, except for {@link #cancel} which 178 * may be called at any time. 179 * 180 * <p>Since {@link Metadata} is not thread-safe, the caller must not access (read or write) {@code 181 * headers} after this point. 182 * 183 * @param responseListener receives response messages 184 * @param headers which can contain extra call metadata, e.g. authentication credentials. 185 * @throws IllegalStateException if a method (including {@code start()}) on this class has been 186 * called. 187 */ start(Listener<RespT> responseListener, Metadata headers)188 public abstract void start(Listener<RespT> responseListener, Metadata headers); 189 190 /** 191 * Requests up to the given number of messages from the call to be delivered to 192 * {@link Listener#onMessage(Object)}. No additional messages will be delivered. 193 * 194 * <p>Message delivery is guaranteed to be sequential in the order received. In addition, the 195 * listener methods will not be accessed concurrently. While it is not guaranteed that the same 196 * thread will always be used, it is guaranteed that only a single thread will access the listener 197 * at a time. 198 * 199 * <p>If it is desired to bypass inbound flow control, a very large number of messages can be 200 * specified (e.g. {@link Integer#MAX_VALUE}). 201 * 202 * <p>If called multiple times, the number of messages able to delivered will be the sum of the 203 * calls. 204 * 205 * <p>This method is safe to call from multiple threads without external synchronization. 206 * 207 * @param numMessages the requested number of messages to be delivered to the listener. Must be 208 * non-negative. 209 * @throws IllegalStateException if call is not {@code start()}ed 210 * @throws IllegalArgumentException if numMessages is negative 211 */ request(int numMessages)212 public abstract void request(int numMessages); 213 214 /** 215 * Prevent any further processing for this {@code ClientCall}. No further messages may be sent or 216 * will be received. The server is informed of cancellations, but may not stop processing the 217 * call. Cancellation is permitted even if previously {@link #halfClose}d. Cancelling an already 218 * {@code cancel()}ed {@code ClientCall} has no effect. 219 * 220 * <p>No other methods on this class can be called after this method has been called. 221 * 222 * <p>It is recommended that at least one of the arguments to be non-{@code null}, to provide 223 * useful debug information. Both argument being null may log warnings and result in suboptimal 224 * performance. Also note that the provided information will not be sent to the server. 225 * 226 * @param message if not {@code null}, will appear as the description of the CANCELLED status 227 * @param cause if not {@code null}, will appear as the cause of the CANCELLED status 228 */ cancel(@ullable String message, @Nullable Throwable cause)229 public abstract void cancel(@Nullable String message, @Nullable Throwable cause); 230 231 /** 232 * Close the call for request message sending. Incoming response messages are unaffected. This 233 * should be called when no more messages will be sent from the client. 234 * 235 * @throws IllegalStateException if call is already {@code halfClose()}d or {@link #cancel}ed 236 */ halfClose()237 public abstract void halfClose(); 238 239 /** 240 * Send a request message to the server. May be called zero or more times depending on how many 241 * messages the server is willing to accept for the operation. 242 * 243 * @param message message to be sent to the server. 244 * @throws IllegalStateException if call is {@link #halfClose}d or explicitly {@link #cancel}ed 245 */ sendMessage(ReqT message)246 public abstract void sendMessage(ReqT message); 247 248 /** 249 * If {@code true}, indicates that the call is capable of sending additional messages 250 * without requiring excessive buffering internally. This event is 251 * just a suggestion and the application is free to ignore it, however doing so may 252 * result in excessive buffering within the call. 253 * 254 * <p>If {@code false}, {@link Listener#onReady()} will be called after {@code isReady()} 255 * transitions to {@code true}. 256 * 257 * <p>If the type of the call is either {@link MethodDescriptor.MethodType#UNARY} or 258 * {@link MethodDescriptor.MethodType#SERVER_STREAMING}, this method may persistently return 259 * false. Calls that send exactly one message should not check this method. 260 * 261 * <p>This abstract class's implementation always returns {@code true}. Implementations generally 262 * override the method. 263 */ isReady()264 public boolean isReady() { 265 return true; 266 } 267 268 /** 269 * Enables per-message compression, if an encoding type has been negotiated. If no message 270 * encoding has been negotiated, this is a no-op. By default per-message compression is enabled, 271 * but may not have any effect if compression is not enabled on the call. 272 */ 273 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1703") setMessageCompression(boolean enabled)274 public void setMessageCompression(boolean enabled) { 275 // noop 276 } 277 278 /** 279 * Returns additional properties of the call. May only be called after {@link Listener#onHeaders} 280 * or {@link Listener#onClose}. If called prematurely, the implementation may throw {@code 281 * IllegalStateException} or return arbitrary {@code Attributes}. 282 * 283 * @return non-{@code null} attributes 284 * @throws IllegalStateException (optional) if called before permitted 285 */ 286 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2607") 287 @Grpc.TransportAttr getAttributes()288 public Attributes getAttributes() { 289 return Attributes.EMPTY; 290 } 291 } 292