Skip to content

Commit

Permalink
fix: Cancel the Timeout Task for HttpJson
Browse files Browse the repository at this point in the history
  • Loading branch information
lqiu96 committed Jan 12, 2024
1 parent 97ae228 commit 4fb5465
Showing 1 changed file with 19 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -121,6 +122,11 @@ final class HttpJsonClientCallImpl<RequestT, ResponseT>
@GuardedBy("lock")
private volatile boolean closed;

// Store the timeout future created by the deadline schedule executor. The future
// can be cancelled if a response has been received before the timeout.
@GuardedBy("lock")
private ScheduledFuture<?> timeoutFuture;

HttpJsonClientCallImpl(
ApiMethodDescriptor<RequestT, ResponseT> methodDescriptor,
String endpoint,
Expand Down Expand Up @@ -176,7 +182,11 @@ public void start(Listener<ResponseT> responseListener, HttpJsonMetadata request
// The future timeout value is guaranteed to not be a negative value as the
// RetryAlgorithm will not retry
long timeoutMs = timeout.toMillis();
this.deadlineCancellationExecutor.schedule(this::timeout, timeoutMs, TimeUnit.MILLISECONDS);
// Assign the scheduled future so that it can be cancelled if the timeout task
// is not needed (response received prior to timeout)
timeoutFuture =
this.deadlineCancellationExecutor.schedule(
this::timeout, timeoutMs, TimeUnit.MILLISECONDS);
}
}

Expand Down Expand Up @@ -430,6 +440,14 @@ private void close(
return;
}
closed = true;

// Cancel the timeout future if there is a timeout task created
if (timeoutFuture != null) {
// timeout() invokes close(), but cancelling a completed task should no-op
timeoutFuture.cancel(true);
timeoutFuture = null;
}

// Best effort task cancellation (to not be confused with task's thread interruption).
// If the task is in blocking I/O waiting for the server response, it will keep waiting for
// the response from the server, but once response is received the task will exit silently.
Expand Down

0 comments on commit 4fb5465

Please sign in to comment.