1111import io .netty .util .concurrent .ProgressiveFuture ;
1212import io .opentelemetry .context .Context ;
1313import io .opentelemetry .context .Scope ;
14- import io .opentelemetry .instrumentation .api .cache . Cache ;
14+ import io .opentelemetry .instrumentation .api .field . VirtualField ;
1515import java .lang .ref .WeakReference ;
1616
1717public final class FutureListenerWrappers {
1818 // note: it's ok if the value is collected prior to the key, since this cache is only used to
1919 // remove the wrapped listener from the netty future, and if the value is collected prior to the
2020 // key, that means it's no longer used (referenced) by the netty future anyways.
2121 //
22- // also note: this is not using VirtualField in case this is ever converted to library
23- // instrumentation, because while the library implementation of VirtualField maintains a weak
24- // reference to its keys, it maintains a strong reference to its values, and in this particular
25- // case the wrapper listener (value) has a strong reference to original listener (key), which will
26- // create a memory leak. which is not a problem in the javaagent's implementation of VirtualField,
27- // since it injects the value directly into the key as a field, and so the value is only retained
28- // strongly by the key, and so they can be collected together.
29- private static final Cache <
22+ // also note: this is using WeakReference as VirtualField value in case this is ever converted to
23+ // library instrumentation, because while the library implementation of VirtualField maintains a
24+ // weak reference to its keys, it maintains a strong reference to its values, and in this
25+ // particular case the wrapper listener (value) has a strong reference to original listener (key),
26+ // which will create a memory leak. which is not a problem in the javaagent's implementation of
27+ // VirtualField, since it injects the value directly into the key as a field, and so the value is
28+ // only retained strongly by the key, and so they can be collected together.
29+ private static final VirtualField <
3030 GenericFutureListener <? extends Future <?>>,
3131 WeakReference <GenericFutureListener <? extends Future <?>>>>
32- wrappers = Cache . weak ( );
32+ wrapperVirtualField = VirtualField . find ( GenericFutureListener . class , WeakReference . class );
3333
3434 private static final ClassValue <Boolean > shouldWrap =
3535 new ClassValue <Boolean >() {
@@ -54,7 +54,7 @@ public static GenericFutureListener<?> wrap(
5454 // collected before we have a chance to make (and return) a strong reference to the wrapper
5555
5656 WeakReference <GenericFutureListener <? extends Future <?>>> resultReference =
57- wrappers .get (delegate );
57+ wrapperVirtualField .get (delegate );
5858
5959 if (resultReference != null ) {
6060 GenericFutureListener <? extends Future <?>> wrapper = resultReference .get ();
@@ -75,14 +75,14 @@ public static GenericFutureListener<?> wrap(
7575 } else {
7676 wrapper = new WrappedFutureListener (context , (GenericFutureListener <Future <?>>) delegate );
7777 }
78- wrappers . put (delegate , new WeakReference <>(wrapper ));
78+ wrapperVirtualField . set (delegate , new WeakReference <>(wrapper ));
7979 return wrapper ;
8080 }
8181
8282 public static GenericFutureListener <? extends Future <?>> getWrapper (
8383 GenericFutureListener <? extends Future <?>> delegate ) {
8484 WeakReference <GenericFutureListener <? extends Future <?>>> wrapperReference =
85- wrappers .get (delegate );
85+ wrapperVirtualField .get (delegate );
8686 if (wrapperReference == null ) {
8787 return delegate ;
8888 }
0 commit comments