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

SLING-10107 [Refactoring] improve resourceresolver handling #63

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

joerghoh
Copy link
Contributor

I refactored the creation of ResourceResolvers (for the bookkeeper subservice) and moved it into a central supplier, which allows also a better monitoring how often ResourceResolvers are actually opened here.

If necessary, further optimizations can be done from here regarding a more efficient use of ResourceResolvers.

Use a Supplier so the LocalStore does not need to know about the
creation of the ResourceResolver and its parameters.
Whenever a resourceResolver for the bookkeeper subservice is required,
a single central supplier is used. This supplier also exposes a gauge
metric so it can be observed how often it is invoked.
@sonarcloud
Copy link

sonarcloud bot commented Feb 1, 2021

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 2 Code Smells

85.7% 85.7% Coverage
0.0% 0.0% Duplication

Copy link
Contributor

@cschneider cschneider left a comment

Choose a reason for hiding this comment

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

I like the idea of externalising the ResourceResolver creation with a Supplier. We should not leak this into the load methods though.
As a further improvement I think we could have a factory class for the resource resolver outside of BookKeeper. The factory could be a DS component that gets the ResourceResolverFactory injected and could provide a supplier via the create method.

return resolverFactory.getServiceResourceResolver(singletonMap(SUBSERVICE, SUBSERVICE_BOOKKEEPER));
} catch (LoginException e) {
log.error("Cannot open ResourceResolver", e);
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think returning null is dangerous here as it later leads to a NPE. How about throwing an exception instead?

}

public ValueMap load() {
public ValueMap load(Supplier<ResourceResolver> supplier) {
Copy link
Contributor

Choose a reason for hiding this comment

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

When using a LocalStore I think it is a bad idea to provide a ResourceResolver supplier. Why do you think this is necessary?

this.resolverFactory = resolverFactory;
this.distributionMetricsService = distributionMetricsService;
// Error queues are enabled when the number
// of retry attempts is limited ; disabled otherwise
this.errorQueueEnabled = (config.getMaxRetries() >= 0);
this.statusStore = new LocalStore(resolverFactory, STORE_TYPE_STATUS, config.getSubAgentName());
this.processedOffsets = new LocalStore(resolverFactory, STORE_TYPE_PACKAGE, config.getSubAgentName());
this.statusStore = new LocalStore(bookKeeperResolver, STORE_TYPE_STATUS, config.getSubAgentName());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's the lifetime of a bookkeeper object? If it's a long-living object, these ResourceResolvers are also long-living, which is a anti-pattern in Sling/JCR.

Copy link
Contributor

@cschneider cschneider Feb 22, 2022

Choose a reason for hiding this comment

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

BookKeeper is long lived. We are only passing resolverFactory there though. The ResourceResolvers should be short lived.

Copy link
Member

Choose a reason for hiding this comment

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

BookKeeper is long lived, but the resources resolvers it builds inside the LocalStore are short lived and kept private. I think the current implementation is good and simple.

@cschneider
Copy link
Contributor

I like the idea of having a metric of resourceResolvers. How about putting the metric inside the standard ResourceResolverFactory in sling?
This way all usages would be measured, not only the ones in this bundle.

@joerghoh
Copy link
Contributor Author

@cschneider you mean a metric into the ResourceResolverFactory? For Oak-based setups we have a metric already there.

@cschneider
Copy link
Contributor

Would this metric already help to diagnose if we open too many resource resolvers?

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.

3 participants