Skip to content

Conversation

@Demogorgon314
Copy link
Member

Motivation

The MetadataCache#getIfCached method will return Optional.empty() if the required path is not cached yet or the cached future is not finished yet, this is normal behavior.

public Optional<T> getIfCached(String path) {
CompletableFuture<Optional<CacheGetResult<T>>> future = objCache.getIfPresent(path);
if (future != null && future.isDone() && !future.isCompletedExceptionally()) {
return future.join().map(CacheGetResult::getValue);
} else {
return Optional.empty();
}
}

We should add a retry mechanism when asserting getIfCached.

Modifications

Add a retry mechanism to assert getIfCached.

Documentation

Check the box below or label this PR directly (if you have committer privilege).

Need to update docs?

  • doc-required

    (If you need help on updating docs, create a doc issue)

  • no-need-doc

    (Please explain why)

  • doc

    (If this PR contains doc changes)

@github-actions github-actions bot added the doc-not-needed Your PR changes do not impact docs label Feb 18, 2022
Copy link
Contributor

@Jason918 Jason918 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codelipenghui codelipenghui added this to the 2.11.0 milestone Feb 24, 2022
@codelipenghui codelipenghui merged commit 8264414 into apache:master Feb 28, 2022
@Demogorgon314 Demogorgon314 deleted the Demogorgon314/fix-metadata-cache-flaky-test branch February 28, 2022 02:15
@lhotari
Copy link
Member

lhotari commented Mar 1, 2022

@Demogorgon314 We should use Awaitility instead of expanding the use of "retryStrategically" which exists in some older test code. Was there a specific reason to not use Awaitility in this PR?

@Demogorgon314
Copy link
Member Author

@lhotari
In this PR, we need ensure objCache.getIfCached(key1) only return Optional.empty() or correct value.

If we use Awaitility.await().untilAsserted(...); here, when objCache.getIfCached(key1) return a wrong value it still retry.

Awaitility.await().untilAsserted(() -> {
    assertEquals(objCache.getIfCached(key1), Optional.of(v));
});

If Awaitility can do what I said, please tell me. Thanks! :-)

@lhotari
Copy link
Member

lhotari commented Mar 1, 2022

@lhotari In this PR, we need ensure objCache.getIfCached(key1) only return Optional.empty() or correct value.

If we use Awaitility.await().untilAsserted(...); here, when objCache.getIfCached(key1) return a wrong value it still retry.

Awaitility.await().untilAsserted(() -> {
    assertEquals(objCache.getIfCached(key1), Optional.of(v));
});

If Awaitility can do what I said, please tell me. Thanks! :-)

I don't see a reason why Awaitility couldn't handle this. Sometimes it's necessary to add .ignoreExceptions() to the Awaitility configuration. This is needed if the assertion throws some other exception than an AssertionError.

Did you try

 Awaitility.await().ignoreExceptions().untilAsserted(() -> {
     assertEquals(objCache.getIfCached(key1), Optional.of(v));
 });

I'm also wondering the logic in retryStrategically. It looks like the check will always pass when i == (retryCount - 1). Perhaps that's the reason why it "works"? @Demogorgon314 please check

public static boolean retryStrategically(Predicate<Void> predicate, int retryCount, long intSleepTimeInMillis)
throws Exception {
for (int i = 0; i < retryCount; i++) {
if (predicate.test(null) || i == (retryCount - 1)) {
return true;
}
Thread.sleep(intSleepTimeInMillis + (intSleepTimeInMillis * i));
}
return false;
}

@lhotari
Copy link
Member

lhotari commented Mar 1, 2022

@Demogorgon314 I made a PR to address the issue, it's #14518 . Please review it.

@lhotari
Copy link
Member

lhotari commented Mar 1, 2022

I closed #14518 since I came to the conclusion that this PR #14373 should be reverted instead.
Besides the retryStrategically being invalid (it will always pass on the last retry), this type of code doesn't make sense to me:

assertEquals(objCache.get(key1).join(), Optional.of(value2));
assertEqualsAndRetry(() -> objCache.getIfCached(key1), Optional.of(value2), Optional.empty());

@Demogorgon314
Copy link
Member Author

@lhotari
Yes, we should remove i == (retryCount - 1) check.

Nicklee007 pushed a commit to Nicklee007/pulsar that referenced this pull request Apr 20, 2022
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request May 9, 2022
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request May 9, 2022
(cherry picked from commit 8264414)
(cherry picked from commit 4e9ab06)
codelipenghui pushed a commit that referenced this pull request Jun 9, 2022
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.

7 participants