• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #18725

pending completion
#18725

push

github-actions

web-flow
Stabilize setMessageCompression() (#10393)

Closes #1703

29163 of 33044 relevant lines covered (88.26%)

0.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.56
/../api/src/main/java/io/grpc/ClientCall.java
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&lt;FooResponse&gt;() {
73
 *     &#64;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
 *     &#64;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> {
1✔
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> {
1✔
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
     */
124
    public void onHeaders(Metadata headers) {}
1✔
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
     */
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
     */
153
    public void onClose(Status status, Metadata trailers) {}
1✔
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
     */
171
    public void onReady() {}
1✔
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
   */
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
   */
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
   */
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
   */
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
   */
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
   */
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
  public void setMessageCompression(boolean enabled) {
274
    // noop
275
  }
×
276

277
  /**
278
   * Returns additional properties of the call. May only be called after {@link Listener#onHeaders}
279
   * or {@link Listener#onClose}. If called prematurely, the implementation may throw {@code
280
   * IllegalStateException} or return arbitrary {@code Attributes}.
281
   *
282
   * @return non-{@code null} attributes
283
   * @throws IllegalStateException (optional) if called before permitted
284
   */
285
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2607")
286
  @Grpc.TransportAttr
287
  public Attributes getAttributes() {
288
    return Attributes.EMPTY;
×
289
  }
290
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc