Draft of per-classloader netty AttributeKey definition
This commit is contained in:
parent
fac3a93445
commit
de6f33c035
|
@ -0,0 +1,33 @@
|
||||||
|
package datadog.trace.agent.tooling;
|
||||||
|
|
||||||
|
import datadog.trace.bootstrap.WeakMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ClassLoaderScopedWeakMap {
|
||||||
|
|
||||||
|
public static final ClassLoaderScopedWeakMap INSTANCE = new ClassLoaderScopedWeakMap();
|
||||||
|
|
||||||
|
private final WeakMap<ClassLoader, Map<Object, Object>> map = WeakMap.Supplier.DEFAULT.get();
|
||||||
|
|
||||||
|
public synchronized Object getOrCreate(
|
||||||
|
ClassLoader classLoader, Object key, Supplier valueSupplier) {
|
||||||
|
Map<Object, Object> classLoaderMap = map.get(classLoader);
|
||||||
|
if (classLoaderMap == null) {
|
||||||
|
classLoaderMap = new HashMap<>();
|
||||||
|
map.put(classLoader, classLoaderMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classLoaderMap.containsKey(key)) {
|
||||||
|
return classLoaderMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value = valueSupplier.get();
|
||||||
|
classLoaderMap.put(key, value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Supplier {
|
||||||
|
Object get();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty40;
|
package datadog.trace.instrumentation.netty40;
|
||||||
|
|
||||||
|
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMap;
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
||||||
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
||||||
|
@ -8,41 +9,49 @@ import io.opentracing.Span;
|
||||||
|
|
||||||
public class AttributeKeys {
|
public class AttributeKeys {
|
||||||
|
|
||||||
|
private static final String PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME =
|
||||||
|
"datadog.trace.instrumentation.netty40.parent.connect.continuation";
|
||||||
|
|
||||||
public static final AttributeKey<TraceScope.Continuation>
|
public static final AttributeKey<TraceScope.Continuation>
|
||||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
||||||
new AttributeKey<>(
|
(AttributeKey<TraceScope.Continuation>)
|
||||||
buildContextSpecificKey(
|
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||||
"datadog.trace.instrumentation.netty40.parent.connect.continuation"));
|
AttributeKey.class.getClassLoader(),
|
||||||
|
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME,
|
||||||
|
new ClassLoaderScopedWeakMap.Supplier() {
|
||||||
|
@Override
|
||||||
|
public Object get() {
|
||||||
|
return new AttributeKey<>(PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private static final String SERVER_ATTRIBUTE_KEY_NAME =
|
||||||
|
HttpServerTracingHandler.class.getName() + ".span";
|
||||||
|
|
||||||
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
|
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
|
||||||
new AttributeKey<>(
|
(AttributeKey<Span>)
|
||||||
buildContextSpecificKey(HttpServerTracingHandler.class.getName() + ".span"));
|
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||||
|
AttributeKey.class.getClassLoader(),
|
||||||
|
SERVER_ATTRIBUTE_KEY_NAME,
|
||||||
|
new ClassLoaderScopedWeakMap.Supplier() {
|
||||||
|
@Override
|
||||||
|
public Object get() {
|
||||||
|
return new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private static final String CLIENT_ATTRIBUTE_KEY_NAME =
|
||||||
|
HttpClientTracingHandler.class.getName() + ".span";
|
||||||
|
|
||||||
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
|
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
|
||||||
new AttributeKey<>(
|
(AttributeKey<Span>)
|
||||||
buildContextSpecificKey(HttpClientTracingHandler.class.getName() + ".span"));
|
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||||
|
AttributeKey.class.getClassLoader(),
|
||||||
/**
|
CLIENT_ATTRIBUTE_KEY_NAME,
|
||||||
* Netty 4.0 before 4.0.26 handled differently how unique attributes where handled, with 4.0.26+
|
new ClassLoaderScopedWeakMap.Supplier() {
|
||||||
* being more lenient with duplicates. We found a use case in Apache Atlas 1.1.0 where for some
|
@Override
|
||||||
* reason, this class gets loaded by multiple class loaders generating an error in 4.0.25- before
|
public Object get() {
|
||||||
* an exception was thrown if that attribute was already defined.
|
return new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
|
||||||
*
|
}
|
||||||
* @param simpleKey The logical key assigned.
|
});
|
||||||
* @return A key scoped to the current class loader in use, if not null.
|
|
||||||
*/
|
|
||||||
private static String buildContextSpecificKey(final String simpleKey) {
|
|
||||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
|
||||||
String key = simpleKey;
|
|
||||||
if (contextClassLoader != null) {
|
|
||||||
key =
|
|
||||||
"ClassLoader."
|
|
||||||
+ contextClassLoader.getClass().getName()
|
|
||||||
+ "."
|
|
||||||
+ contextClassLoader.hashCode()
|
|
||||||
+ "."
|
|
||||||
+ key;
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue