Skip to content
This repository was archived by the owner on Apr 7, 2026. It is now read-only.

Commit b9e5d4e

Browse files
committed
chore: handle unary gRPC call ordering in KeyAwareChannel
1 parent 2fd403f commit b9e5d4e

1 file changed

Lines changed: 75 additions & 1 deletion

File tree

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/KeyAwareChannel.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ static final class KeyAwareClientCall<RequestT, ResponseT>
245245
@Nullable private ChannelEndpoint selectedEndpoint;
246246
@Nullable private ByteString transactionIdToClear;
247247
private boolean allowDefaultAffinity;
248+
private long pendingRequests;
249+
private boolean pendingHalfClose;
250+
@Nullable private Boolean pendingMessageCompression;
251+
private boolean cancelled;
252+
@Nullable private String cancelMessage;
253+
@Nullable private Throwable cancelCause;
248254

249255
KeyAwareClientCall(
250256
KeyAwareChannel parentChannel,
@@ -268,11 +274,22 @@ protected ClientCall<RequestT, ResponseT> delegate() {
268274
public void start(Listener<ResponseT> responseListener, Metadata headers) {
269275
this.responseListener = new KeyAwareClientCallListener<>(responseListener, this);
270276
this.headers = headers;
277+
if (cancelled) {
278+
this.responseListener.onClose(
279+
io.grpc.Status.CANCELLED.withDescription(cancelMessage).withCause(cancelCause),
280+
new Metadata());
281+
}
271282
}
272283

273284
@Override
274285
@SuppressWarnings("unchecked")
275286
public void sendMessage(RequestT message) {
287+
if (cancelled) {
288+
return;
289+
}
290+
if (responseListener == null || headers == null) {
291+
throw new IllegalStateException("start must be called before sendMessage");
292+
}
276293
ChannelEndpoint endpoint = null;
277294
ChannelFinder finder = null;
278295

@@ -326,16 +343,23 @@ public void sendMessage(RequestT message) {
326343
this.channelFinder = finder;
327344

328345
delegate = endpoint.getChannel().newCall(methodDescriptor, callOptions);
346+
if (pendingMessageCompression != null) {
347+
delegate.setMessageCompression(pendingMessageCompression);
348+
}
329349
delegate.start(responseListener, headers);
350+
drainPendingRequests();
330351
delegate.sendMessage(message);
352+
if (pendingHalfClose) {
353+
delegate.halfClose();
354+
}
331355
}
332356

333357
@Override
334358
public void halfClose() {
335359
if (delegate != null) {
336360
delegate.halfClose();
337361
} else {
338-
throw new IllegalStateException("halfClose called before sendMessage");
362+
pendingHalfClose = true;
339363
}
340364
}
341365

@@ -346,6 +370,56 @@ public void cancel(@Nullable String message, @Nullable Throwable cause) {
346370
} else if (responseListener != null) {
347371
responseListener.onClose(
348372
io.grpc.Status.CANCELLED.withDescription(message).withCause(cause), new Metadata());
373+
cancelled = true;
374+
cancelMessage = message;
375+
cancelCause = cause;
376+
} else {
377+
cancelled = true;
378+
cancelMessage = message;
379+
cancelCause = cause;
380+
}
381+
}
382+
383+
@Override
384+
public void request(int numMessages) {
385+
if (delegate != null) {
386+
delegate.request(numMessages);
387+
return;
388+
}
389+
if (numMessages <= 0) {
390+
return;
391+
}
392+
long updated = pendingRequests + numMessages;
393+
if (updated < 0L) {
394+
updated = Long.MAX_VALUE;
395+
}
396+
pendingRequests = updated;
397+
}
398+
399+
@Override
400+
public boolean isReady() {
401+
if (delegate == null) {
402+
return false;
403+
}
404+
return delegate.isReady();
405+
}
406+
407+
@Override
408+
public void setMessageCompression(boolean enabled) {
409+
if (delegate != null) {
410+
delegate.setMessageCompression(enabled);
411+
} else {
412+
pendingMessageCompression = enabled;
413+
}
414+
}
415+
416+
private void drainPendingRequests() {
417+
long requests = pendingRequests;
418+
pendingRequests = 0L;
419+
while (requests > 0) {
420+
int batch = requests > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) requests;
421+
delegate.request(batch);
422+
requests -= batch;
349423
}
350424
}
351425

0 commit comments

Comments
 (0)