-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate Guava cache usage to Caffeine #295
Migrate Guava cache usage to Caffeine #295
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-applied the comments from #286.
@@ -17,7 +18,7 @@ | |||
* Return the value associated with the instance in this ExtensionHolder. If the value is not present it will be | |||
* initialized (in a thread-safe manner) using valueLoader. | |||
*/ | |||
public T getExtension(Object instance, Callable<T> valueLoader); | |||
public T getExtension(Object instance, Supplier<T> valueLoader); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found only one implementation of this interface. If it is used elsewhere we should revert this change and introduce a try/catch
construct in the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep this change.
activeTokens = CacheBuilder.newBuilder() | ||
.concurrencyLevel(8) | ||
activeTokens = Caffeine.newBuilder() | ||
.initialCapacity(8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For context see the discussion @ #286 (comment). We should consider dropping this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are going to keep this change as is with capacity set to 8. I'm creating a research spike to unblock getting this merged and investigate whether resizing makes sense.
.expireAfterAccess(timeOutMilli, TimeUnit.MILLISECONDS) | ||
.executor(Runnable::run) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Runnable::run
is here because one of the tests expects to see the effects of the removal notification in a timely manner. See the wiki on how Caffeine may schedule this kind of work on another thread. Alternatively the test could be tweaked. If the current behavior is desired, perhaps .executor(Runnable::run)
should also be added in AsyncTransactionService
.
newrelic-agent/src/main/java/com/newrelic/agent/extension/ExtensionRewriter.java
Show resolved
Hide resolved
@@ -128,7 +128,7 @@ public ClassLoaderClassTransformer(InstrumentationProxy instrumentation, Set<Str | |||
// Try to use a custom Guava-based extension template to make NewField access better | |||
try { | |||
extensionTemplate = WeaveUtils.convertToClassNode(WeaveUtils.getClassBytesFromClassLoaderResource( | |||
GuavaBackedExtensionClass.class.getName(), GuavaBackedExtensionClass.class.getClassLoader())); | |||
CaffeineBackedExtensionClass.class.getName(), CaffeineBackedExtensionClass.class.getClassLoader())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GuavaBackedExtensionClass
is now Caffeine-backend, so a rename seemed in order.
key, | ||
k -> metricName == null | ||
? sig.getMetricNameFormat(key.invocationTargetClassName, flags) | ||
: new SimpleMetricNameFormat(getTracerMetricName(key.invocationTargetClassName, sig.getClassName(), metricName))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the if
condition is now only evaluated on cache misses.
// Make sure we pick up this Caffeine reference. | ||
Caffeine<Object, Object> newBuilder = Caffeine.newBuilder(); | ||
// Make sure we pick up this Guava reference. | ||
ImmutableSet<Object> set = ImmutableSet.of(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to my question above: no idea whether these test changes make sense.
@@ -239,7 +239,8 @@ public void testMaxInvalidClassLoaders() throws IOException { | |||
wpm.weave(cl, "com/newrelic/weave/weavepackage/WeavePackageManagerTest$NewNoMatchClass", | |||
WeaveTestUtils.getClassBytes("com.newrelic.weave.weavepackage.WeavePackageManagerTest$NewNoMatchClass")); | |||
} | |||
Assert.assertTrue(WeavePackageManager.MAX_INVALID_PACKAGE_CACHE >= wpm.invalidPackages.size()); | |||
wpm.invalidPackages.cleanUp(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the wiki; Caffeine's size-based eviction may cause the cache to grow slightly larger than configured. Here we trigger an explicit cleanup to make sure the test passes. Under normal operation this kind of cleanup is performed in the context of subsequent cache operations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one .cleanUp()
call wasn't enough; added a commit with a more robust fix.
@Stephan202 Just a heads up that we are planning to review this after releasing agent version 7.0.0, which we are targeting for June 7th. Thank you for your contribution and patience! |
No hurry :) For when the time comes: google/guava#5571 provides additional background. |
@Stephan202 I've started doing some testing for this PR. I'm curious if this build resolves the deadlock we were seeing in the support ticket where discussing this change to Caffeine originally came up. Are you able to run this agent build in that environment? |
@tbradellis so far I did not attempt to deploy this code. Given our setup this wouldn't be impossible per se, but also a bit more work than I can commit to right now. I'll make a note in case I do find some spare time. 🤞 (For the time being we're still running with |
Hey @Stephan202 . I'm working to get this merged. I need to rebase and I also have a few minor changes for some of the comments. |
Hi @tbradellis. It turns out that the "Allow edits from maintainers" feature isn't available for PRs created from organization accounts (such as If you have any questions about this or the code, let me know. Tnx for picking this up! |
648f3c1
to
c25ab73
Compare
I've rebased the branch on latest W.r.t. open tasks, cursory inspection surfaces two more:
|
It's not clear to me whether/how the Scala test failures relate to the changes in this PR. |
We have an issue with out scala tests that we are working to fix. It's also a race condition so, once it reruns a few times it'll pass. |
bc93cf3
to
08997f0
Compare
@Stephan202 It looks like I stepped on your commits when I had to --reset-author to get my license/cla accepted. I'll correct that. |
Hi @Stephan202 check your email when you have a moment (and your junk folder just in case) I tried to send you a message |
08997f0
to
7e82d80
Compare
@kford-newrelic it took me a while to find that email, as a GMail filter got hold of it; replied :) @tbradellis I took the liberty to fix the author situation in this PR. (I still had an old version of the branch, so simply cherry-picked your commit on top of it and then rebased; there were no conflicts and the final diff is identical.) |
This PR is a replacement of #286, which was closed as a side effect of the deletion of its base branch. For the original context, see #258. This migration from Guava to Caffeine was unlocked by the migration to Java 8 in the context of #276.
I'll re-apply the comments from the other PR, so as to ease the review effort.