You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2020/04/08 12:41:34 UTC

[httpcomponents-core] branch master updated: Added exception callback to async server implementations enabling logging of unexpected and fatal exceptions in the server side protocol handlers

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 12ad08b  Added exception callback to async server implementations enabling logging of unexpected and fatal exceptions in the server side protocol handlers
12ad08b is described below

commit 12ad08b3adaf162236bbb081b09168b9ea3984ea
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Apr 5 14:53:17 2020 +0200

    Added exception callback to async server implementations enabling logging of unexpected and fatal exceptions in the server side protocol handlers
---
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  4 ++--
 .../http/impl/bootstrap/AsyncServerBootstrap.java  |  4 ++--
 ...yncServerFilterChainExchangeHandlerFactory.java | 13 +++++++++++-
 .../BasicAsyncServerExpectationDecorator.java      | 24 ++++++++++++++--------
 4 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
index 071fa74..6b2c8d9 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
@@ -407,13 +407,13 @@ public class H2ServerBootstrap {
                 current = current.getPrevious();
             }
 
-            handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain);
+            handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain, exceptionCallback);
         } else {
             handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry, new Decorator<AsyncServerExchangeHandler>() {
 
                 @Override
                 public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                    return new BasicAsyncServerExpectationDecorator(handler);
+                    return new BasicAsyncServerExpectationDecorator(handler, exceptionCallback);
                 }
 
             });
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
index d7b0560..4eb47af 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
@@ -385,13 +385,13 @@ public class AsyncServerBootstrap {
                 current = current.getPrevious();
             }
 
-            handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain);
+            handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain, exceptionCallback);
         } else {
             handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry, new Decorator<AsyncServerExchangeHandler>() {
 
                 @Override
                 public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                    return new BasicAsyncServerExpectationDecorator(handler);
+                    return new BasicAsyncServerExpectationDecorator(handler, exceptionCallback);
                 }
 
             });
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java
index faaa6ff..5f47bcb 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java
@@ -32,6 +32,7 @@ import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
@@ -60,9 +61,16 @@ import org.apache.hc.core5.util.Asserts;
 public final class AsyncServerFilterChainExchangeHandlerFactory implements HandlerFactory<AsyncServerExchangeHandler> {
 
     private final AsyncServerFilterChainElement filterChain;
+    private final Callback<Exception> exceptionCallback;
 
-    public AsyncServerFilterChainExchangeHandlerFactory(final AsyncServerFilterChainElement filterChain) {
+    public AsyncServerFilterChainExchangeHandlerFactory(final AsyncServerFilterChainElement filterChain,
+                                                        final Callback<Exception> exceptionCallback) {
         this.filterChain = Args.notNull(filterChain, "Filter chain");
+        this.exceptionCallback = exceptionCallback;
+    }
+
+    public AsyncServerFilterChainExchangeHandlerFactory(final AsyncServerFilterChainElement filterChain) {
+        this(filterChain, null);
     }
 
     @Override
@@ -105,6 +113,9 @@ public final class AsyncServerFilterChainExchangeHandlerFactory implements Handl
 
             @Override
             public void failed(final Exception cause) {
+                if (exceptionCallback != null) {
+                    exceptionCallback.execute(cause);
+                }
                 final AsyncResponseProducer handler = responseProducerRef.get();
                 if (handler != null) {
                     handler.failed(cause);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java
index 09194e6..441e2ae 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java
@@ -31,6 +31,7 @@ import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HeaderElements;
@@ -57,13 +58,20 @@ import org.apache.hc.core5.util.Args;
 public class BasicAsyncServerExpectationDecorator implements AsyncServerExchangeHandler {
 
     private final AsyncServerExchangeHandler handler;
+    private final Callback<Exception> exceptionCallback;
     private final AtomicReference<AsyncResponseProducer> responseProducerRef;
 
-    public BasicAsyncServerExpectationDecorator(final AsyncServerExchangeHandler handler) {
+    public BasicAsyncServerExpectationDecorator(final AsyncServerExchangeHandler handler,
+                                                final Callback<Exception> exceptionCallback) {
         this.handler = Args.notNull(handler, "Handler");
+        this.exceptionCallback = exceptionCallback;
         this.responseProducerRef = new AtomicReference<>(null);
     }
 
+    public BasicAsyncServerExpectationDecorator(final AsyncServerExchangeHandler handler) {
+        this(handler, null);
+    }
+
     protected AsyncResponseProducer verify(
             final HttpRequest request,
             final HttpContext context) throws IOException, HttpException {
@@ -135,14 +143,14 @@ public class BasicAsyncServerExpectationDecorator implements AsyncServerExchange
 
     @Override
     public final void failed(final Exception cause) {
-        try {
+        if (exceptionCallback != null) {
+            exceptionCallback.execute(cause);
+        }
+        final AsyncResponseProducer dataProducer = responseProducerRef.get();
+        if (dataProducer == null) {
             handler.failed(cause);
-            final AsyncResponseProducer dataProducer = responseProducerRef.getAndSet(null);
-            if (dataProducer != null) {
-                dataProducer.failed(cause);
-            }
-        } finally {
-            releaseResources();
+        } else {
+            dataProducer.failed(cause);
         }
     }