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

Update EvaluatorBuilder cache to be thread safe #62

Merged
merged 1 commit into from
Nov 10, 2023

Conversation

pkwarren
Copy link
Member

@pkwarren pkwarren commented Nov 10, 2023

Update EvaluatorBuilder to add locking around cache misses to avoid concurrent modification to a HashMap. Migrate all of the code to build a new cache to an inner class to better separate code concerns.

Fixes #50.

Update EvaluatorBuilder to add locking around cache misses to avoid
concurrent modification to a HashMap. Migrate all of the code to build a
new cache to an inner class to better separate code concerns.
@pkwarren pkwarren requested review from rodaine and Alfus November 10, 2023 19:26
}
msgEval.append(new CelPrograms(compiledPrograms));
}
private static class DescriptorCacheBuilder {
Copy link
Member Author

Choose a reason for hiding this comment

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

I'd recommend viewing the rest of this ignoring whitespace - it is really just moving functions inside this inner static class.

resolver.resolveMessageConstraints(descriptor, EXTENSION_REGISTRY);
if (msgConstraints.getDisabled()) {
return;
synchronized (this) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the key change - if we have a cache miss we'll check again (in case another thread beat us in the meantime) and if that fails, we'll rebuild a brand new cache map from the current one and the descriptor.

@@ -54,8 +55,7 @@ public class EvaluatorBuilder {
EXTENSION_REGISTRY.add(ValidateProto.oneof);
}

private final Map<Descriptor, Evaluator> evaluatorMap = new HashMap<>();
private final ConstraintResolver resolver = new ConstraintResolver();
private volatile ImmutableMap<Descriptor, Evaluator> evaluatorCache = ImmutableMap.of();
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't have to use immutablemap here, but I thought it was a good indication to make it clear that this cache won't be modified - if we have a cache miss we'll create a new map.

@pkwarren pkwarren merged commit 07779ce into main Nov 10, 2023
5 checks passed
@pkwarren pkwarren deleted the pkw/issue-50-thread-safety branch November 10, 2023 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Validator/EvaluatorBuilder aren't thread safe
2 participants