Draft of per-classloader netty AttributeKey definition

This commit is contained in:
Luca Abbati 2019-07-08 18:41:48 -04:00
parent fac3a93445
commit de6f33c035
No known key found for this signature in database
GPG Key ID: 74DBB952D9BA17F2
2 changed files with 73 additions and 31 deletions

View File

@ -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();
}
}

View File

@ -1,5 +1,6 @@
package datadog.trace.instrumentation.netty40;
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMap;
import datadog.trace.context.TraceScope;
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
@ -8,41 +9,49 @@ import io.opentracing.Span;
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>
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
new AttributeKey<>(
buildContextSpecificKey(
"datadog.trace.instrumentation.netty40.parent.connect.continuation"));
(AttributeKey<TraceScope.Continuation>)
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
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 =
new AttributeKey<>(
buildContextSpecificKey(HttpServerTracingHandler.class.getName() + ".span"));
(AttributeKey<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 =
new AttributeKey<>(
buildContextSpecificKey(HttpClientTracingHandler.class.getName() + ".span"));
/**
* Netty 4.0 before 4.0.26 handled differently how unique attributes where handled, with 4.0.26+
* being more lenient with duplicates. We found a use case in Apache Atlas 1.1.0 where for some
* reason, this class gets loaded by multiple class loaders generating an error in 4.0.25- before
* an exception was thrown if that attribute was already defined.
*
* @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;
(AttributeKey<Span>)
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
AttributeKey.class.getClassLoader(),
CLIENT_ATTRIBUTE_KEY_NAME,
new ClassLoaderScopedWeakMap.Supplier() {
@Override
public Object get() {
return new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
}
});
}