Skip to content
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

Fix deadlock if compute function throw a RuntimeException #2799

Closed
wants to merge 3 commits into from

Conversation

imario42
Copy link

If the computeIfAbsent methods fails with a runtime exception, successive calls to computeIfAbsent lock due to a call to oldValue.waitForValue which never will receive a value then.

A test case to reproduce this behavior - the second computeIfAbsent will never return and your app is frozen.
The pull request restores the previous state of the cache on RuntimeException and the test will finish correctly.

`public class TestGuava extends TestCase
{
private Cache<String, Boolean> cache = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterAccess(30, TimeUnit.SECONDS)
.build();
private Map<String, Boolean> cacheMap = cache.asMap();

private final static Boolean TEST_BOOLEAN = new Boolean(true);
public void testComputeException()
{
    try
    {
        cacheMap.computeIfAbsent("a", key ->
        {
            throw new IllegalArgumentException();
        });

        fail();
    }
    catch (Exception e)
    {
        // expected
    }

    Boolean ret = cacheMap.computeIfAbsent("a", key -> {
        return TEST_BOOLEAN;
    });

    assertEquals(Boolean.TRUE, ret);
    assertSame(TEST_BOOLEAN, ret);

    ret = cacheMap.computeIfAbsent("a", key -> {
        return new Boolean(true); // should not create a new entry
    });

    assertEquals(Boolean.TRUE, ret);
    assertSame(TEST_BOOLEAN, ret);
}

}`

@googlebot
Copy link
Collaborator

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

@imario42
Copy link
Author

I signed it!

@googlebot
Copy link
Collaborator

CLAs look good, thanks!

@ben-manes
Copy link
Contributor

This should rethrow Throwable in case of an Error.

@imario42
Copy link
Author

imario42 commented May 1, 2017

@ben-manes : You mean instead of catching "just" the RuntimeException (which actually is rethrown) to catch a Throwable, right? Else, I don't know which "Error" you mean.

@ben-manes
Copy link
Contributor

Yes, use Throwable. Otherwise a java.lang.Error or sneakily thrown checked exception will not be handled.

@imario42
Copy link
Author

imario42 commented May 1, 2017

Well, thanks to Java 8 that one was easy to fix. Done!

@imario42
Copy link
Author

imario42 commented Aug 9, 2017

I'd like to ask if there is something else I can do that this fix gets merged?

@schlosna
Copy link

I would also like to see this fix merged and released soon as I've seen a couple separate projects hit deadlocks on cache compute and the fix for #2743 did not fully handle the above mentioned failure cases.

Thanks!

@dawid-stosur
Copy link

dawid-stosur commented Jul 16, 2018

We also experienced this issue on PROD so also would like to see it merged and released ASAP as we use this cache extensively in our projects.

@imario42
Copy link
Author

Maybe have a look at https://github.com/ben-manes/caffeine which does not suffer from this bug?

@ben-manes
Copy link
Contributor

I think this was fixed in 8210828 (25.1)

@netdpb
Copy link
Member

netdpb commented Oct 25, 2019

Closing this PR as it looks like the bug was fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants