-
Notifications
You must be signed in to change notification settings - Fork 586
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 QuerierService.GetProfileStats #3090
Conversation
newQuerierParams := &querier.NewQuerierParams{ | ||
Cfg: f.Cfg.Querier, | ||
StoreGatewayCfg: f.Cfg.StoreGateway, | ||
Overrides: f.Overrides, | ||
CfgProvider: f.Overrides, | ||
StorageBucket: f.storageBucket, | ||
IngestersRing: f.ring, | ||
Reg: f.reg, | ||
Logger: log.With(f.logger, "component", "querier"), | ||
ClientOptions: []connect.ClientOption{f.auth}, | ||
} | ||
querierSvc, err := querier.New(newQuerierParams) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very opinionated but still: many people prefer passing dependencies as function arguments because it is less verbose and, more importantly, provides some type safety guarantees. Your code simply won't compile if you forget some of your dependencies (though there are still many other ways to make mistakes).
In Pyroscope, from what I can tell, dependencies are mostly passed as explicit arguments in most places. I'm open to any approach; I just wanted to draw your attention to this matter. If you think it's better to use a struct here, then let's go with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no perfect solution for this. You mentioned most of the pros and cons of both approaches.
Personally I find the code snippet you highlighted more readable compared to
querierSvc, err := querier.New(f.Cfg.Querier, f.ring, nil, storeGatewayQuerier, f.reg, log.With(f.logger, "component", "querier"), f.auth)
or:
querierSvc, err := querier.New(
f.Cfg.Querier,
f.ring,
nil,
storeGatewayQuerier,
f.reg,
log.With(f.logger, "component", "querier"),
f.auth
)
I find the struct approach more readable because I can see what is being passed on without switching contexts and without paying attention to the argument order. The readability gains are higher when the number of arguments is higher.
As for safety, I expect constructor functions like this to perform validation on the input. E.g., we are already sending a nil
in my last example which is maybe fine in this context but not in another and the function itself has to enforce this.
I am also open to any approach and would be curious to hear what others think.
@simonswine @bryanhuhta @korniltsev @petethepig any thoughts?
Adds a new API for returning simple profile statistics. Right now limited to a flag indicating if profiling data exists and the timestamp of the oldest and newest profile if available. More stats could be added in the future (e.g., number of unique series, number of profiles, samples, etc.).
Closes #3003
cc @grafakus