-
Notifications
You must be signed in to change notification settings - Fork 291
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix native-image generation of reactive applications (#8012)
* Refactor registration of AsyncResult extensions so it doesn't pull in AsyncResultDecorator * Rebuild AsyncResultExtensions at native-image runtime
- Loading branch information
Showing
17 changed files
with
152 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
...in/java/datadog/trace/bootstrap/instrumentation/java/concurrent/AsyncResultExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package datadog.trace.bootstrap.instrumentation.java.concurrent; | ||
|
||
import datadog.trace.bootstrap.instrumentation.api.AgentSpan; | ||
|
||
/** | ||
* This interface defines asynchronous result type support extension. It allows deferring the | ||
* support implementations where types are available on classpath. | ||
*/ | ||
public interface AsyncResultExtension { | ||
/** | ||
* Checks whether this extensions support a result type. | ||
* | ||
* @param result The result type to check. | ||
* @return {@code true} if the type is supported by this extension, {@code false} otherwise. | ||
*/ | ||
boolean supports(Class<?> result); | ||
|
||
/** | ||
* Applies the extension to the async result. | ||
* | ||
* @param result The async result. | ||
* @param span The related span. | ||
* @return The result object to return (can be the original result if not modified), or {@code | ||
* null} if the extension could not be applied. | ||
*/ | ||
Object apply(Object result, AgentSpan span); | ||
} |
67 changes: 67 additions & 0 deletions
67
...n/java/datadog/trace/bootstrap/instrumentation/java/concurrent/AsyncResultExtensions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package datadog.trace.bootstrap.instrumentation.java.concurrent; | ||
|
||
import static java.util.Collections.singletonList; | ||
|
||
import datadog.trace.bootstrap.instrumentation.api.AgentSpan; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.CompletionException; | ||
import java.util.concurrent.CompletionStage; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.function.BiConsumer; | ||
|
||
public final class AsyncResultExtensions { | ||
private static final List<AsyncResultExtension> EXTENSIONS = | ||
new CopyOnWriteArrayList<>(singletonList(new CompletableAsyncResultExtension())); | ||
|
||
/** | ||
* Registers an extension to add supported async types. | ||
* | ||
* @param extension The extension to register. | ||
*/ | ||
public static void register(AsyncResultExtension extension) { | ||
if (extension != null) { | ||
EXTENSIONS.add(extension); | ||
} | ||
} | ||
|
||
/** Returns the list of currently registered extensions. */ | ||
public static List<AsyncResultExtension> registered() { | ||
return EXTENSIONS; | ||
} | ||
|
||
static final class CompletableAsyncResultExtension implements AsyncResultExtension { | ||
@Override | ||
public boolean supports(Class<?> result) { | ||
return CompletableFuture.class.isAssignableFrom(result) | ||
|| CompletionStage.class.isAssignableFrom(result); | ||
} | ||
|
||
@Override | ||
public Object apply(Object result, AgentSpan span) { | ||
if (result instanceof CompletableFuture<?>) { | ||
CompletableFuture<?> completableFuture = (CompletableFuture<?>) result; | ||
if (!completableFuture.isDone() && !completableFuture.isCancelled()) { | ||
return completableFuture.whenComplete(finishSpan(span)); | ||
} | ||
} else if (result instanceof CompletionStage<?>) { | ||
CompletionStage<?> completionStage = (CompletionStage<?>) result; | ||
return completionStage.whenComplete(finishSpan(span)); | ||
} | ||
return null; | ||
} | ||
|
||
private <T> BiConsumer<T, Throwable> finishSpan(AgentSpan span) { | ||
return (o, throwable) -> { | ||
if (throwable != null) { | ||
span.addThrowable( | ||
throwable instanceof ExecutionException || throwable instanceof CompletionException | ||
? throwable.getCause() | ||
: throwable); | ||
} | ||
span.finish(); | ||
}; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 8 additions & 8 deletions
16
...veStreamsAsyncResultSupportExtension.java → .../ReactiveStreamsAsyncResultExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.