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

Add context objects to StatisticsCollector methods #120

Conversation

AlexandreCarlton
Copy link
Collaborator

The StatisticsCollector interface is useful for gathering basic
metrics about data loaders, but is limited in that we are unable to pass
in any sort of context (key or call). This would allow us to obtain more
insightful metrics (for example, we would be able to break down metrics
based on the GraphQL operation name).

To this end, we add *StatisticsContext objects to each
StatisticsCollector method; we provide distinct implementations for
each one rather than a generic catch-all so that we may evolve them
independently as needed.

}

@Override
public long incrementCacheHitCount() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The diff is a bit clobbered because I decided to order the methods according to the interface.

The `StatisticsCollector` interface is useful for gathering basic
metrics about data loaders, but is limited in that we are unable to pass
in any sort of context (key or call). This would allow us to obtain more
insightful metrics (for example, we would be able to break down metrics
based on the GraphQL operation name).

To this end, we add `*StatisticsContext` objects to each
`StatisticsCollector` method; we provide distinct implementations for
each one rather than a generic catch-all so that we may evolve them
independently as needed.
}

public IncrementBatchLoadCountByStatisticsContext(K key, Object callContext) {
this.keys = Collections.singletonList(key);
Copy link
Member

Choose a reason for hiding this comment

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

use this() to call back to the one place

this.callContext = callContext;
}

public IncrementCacheHitCountStatisticsContext(K key) {
Copy link
Member

Choose a reason for hiding this comment

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

use this(..)

Copy link
Member

@bbakerman bbakerman left a comment

Choose a reason for hiding this comment

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

This looks spot on - it passes the old tests (because they never used the new context) but others would be able to take advantage of it

* @deprecated use {@link #incrementLoadCount(IncrementLoadCountStatisticsContext)}
* @return the current value after increment
*/
@Deprecated
long incrementLoadCount();
Copy link
Member

Choose a reason for hiding this comment

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

Nice! Great way to evolve the API

Copy link
Member

@bbakerman bbakerman left a comment

Choose a reason for hiding this comment

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

Add an extra test to show it carries over the expecetd keys and contexts

collector.incrementLoadCount();
collector.incrementBatchLoadCountBy(1);
collector.incrementLoadCount(new IncrementLoadCountStatisticsContext<>(1, null));
collector.incrementBatchLoadCountBy(1, new IncrementBatchLoadCountByStatisticsContext<>(1, null));

BatchLoader<String, String> batchLoader = CompletableFuture::completedFuture;
DataLoaderOptions loaderOptions = DataLoaderOptions.newOptions().setStatisticsCollector(() -> collector);
Copy link
Member

Choose a reason for hiding this comment

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

I think we need a test such that we tets that give a load(K,context) in the data loader, we get K and context passed into the StatsCollector. That is the innards of DataLoader do what we expect them to do

* @return the current value after increment
*/
default <K> long incrementLoadCount(IncrementLoadCountStatisticsContext<K> context) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In hindsight, rather than parameterise each new method, would it have made more sense to parameterise the entire class on K?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I explored this in a bit more detail; having to pass in a type parameter into certain contexts (ThreadLocalStatisticsCollector's static collector and DataLoaderOptions) made this awkward; so I'll leave this as-is.

@bbakerman bbakerman merged commit 7a59ead into graphql-java:master Jul 16, 2022
@bbakerman bbakerman added this to the 3.2 milestone Jul 16, 2022
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.

None yet

2 participants