From b76d86021f13a53323e457954c9a4298e8385677 Mon Sep 17 00:00:00 2001 From: Alex Panchenko <440271+panchenko@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:31:29 +0200 Subject: [PATCH 1/2] ignore IllegalStateException from asyncContext.complete() --- .../io/grpc/servlet/AsyncServletOutputStreamWriter.java | 8 ++++++-- .../main/java/io/grpc/servlet/ServletServerStream.java | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java b/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java index 8c0c6ec6512..5fed704f9a4 100644 --- a/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java +++ b/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java @@ -124,7 +124,11 @@ public void finest(String str, Object... params) { transportState.runOnTransportThread( () -> { transportState.complete(); - asyncContext.complete(); + try { + asyncContext.complete(); + } catch (IllegalStateException ignored) { + // Tomcat can throw "Calling [asyncComplete()] is not valid for a request with Async state [COMPLETING]" + } log.fine("call completed"); }); }; @@ -254,7 +258,7 @@ interface ActionItem { @VisibleForTesting // Lincheck test can not run with java.util.logging dependency. interface Log { default boolean isLoggable(Level level) { - return false; + return false; } default void fine(String str, Object...params) {} diff --git a/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java b/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java index 5d11abf0f90..7af2519454d 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java @@ -300,7 +300,11 @@ public void cancel(Status status) { close(Status.CANCELLED.withCause(status.asRuntimeException()), new Metadata()); CountDownLatch countDownLatch = new CountDownLatch(1); transportState.runOnTransportThread(() -> { - asyncCtx.complete(); + try { + asyncCtx.complete(); + } catch (IllegalStateException ignored) { + // Tomcat can throw "Calling [asyncComplete()] is not valid for a request with Async state [COMPLETING]" + } countDownLatch.countDown(); }); try { From 20feb575dcf2140a5ffb1f5e89ea112dbb9acef9 Mon Sep 17 00:00:00 2001 From: Alex Panchenko <440271+panchenko@users.noreply.github.com> Date: Mon, 13 Jan 2025 22:09:02 +0200 Subject: [PATCH 2/2] fix checkstyle --- .../java/io/grpc/servlet/AsyncServletOutputStreamWriter.java | 3 ++- servlet/src/main/java/io/grpc/servlet/ServletServerStream.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java b/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java index 5fed704f9a4..23a3b94dee8 100644 --- a/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java +++ b/servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java @@ -127,7 +127,8 @@ public void finest(String str, Object... params) { try { asyncContext.complete(); } catch (IllegalStateException ignored) { - // Tomcat can throw "Calling [asyncComplete()] is not valid for a request with Async state [COMPLETING]" + // Tomcat can throw: + // Calling [asyncComplete()] is not valid for a request with Async state [COMPLETING] } log.fine("call completed"); }); diff --git a/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java b/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java index 7af2519454d..00674097cf8 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletServerStream.java @@ -303,7 +303,8 @@ public void cancel(Status status) { try { asyncCtx.complete(); } catch (IllegalStateException ignored) { - // Tomcat can throw "Calling [asyncComplete()] is not valid for a request with Async state [COMPLETING]" + // Tomcat can throw: + // Calling [asyncComplete()] is not valid for a request with Async state [COMPLETING] } countDownLatch.countDown(); });