-
Notifications
You must be signed in to change notification settings - Fork 82
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
feat(metrics): Enhance Family's flexibility #230
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Wenbo Zhang <[email protected]>
@mxinden PTAL, thanks! |
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.
Thanks for the thorough patch.
I am fine with get
. I don't think we should expose the internals of Family
, e.g. via with_metrics
.
/// ``` | ||
pub fn with_metrics<F, R>(&self, f: F) -> R | ||
where | ||
F: FnOnce(&RwLock<HashMap<S, M>>) -> R |
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.
I don't think we should expose the internals of Family
on the public API.
Say we want to change self.metrics
to a different datastructure. That would be a breaking change.
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.
I don't think we should expose the internals of Family on the public API.
Say we want to change self.metrics to a different datastructure. That would be a breaking change.
Agree with your point of view, do you think improvements like the following are acceptable?
pub fn with_metrics<F, R>(&self, f: F) -> R
where
F: FnOnce(&dyn MetricsView<S, M>) -> R
{
struct MetricsViewImpl<'a, S, M>(&'a RwLock<HashMap<S, M>>);
impl<'a, S, M> MetricsView<S, M> for MetricsViewImpl<'a, S, M> {
fn get(&self, key: &S) -> Option<&M> {
self.0.read().get(key)
}
// other methods
}
f(&MetricsViewImpl(&self.metrics))
}
pub trait MetricsView<S, M> {
fn get(&self, key: &S) -> Option<&M>;
// other methods
}
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.
I don't think the above use-case justifies introducing this much complexity.
Would implementing your own Family
metric type suffice for now?
For the sake of getting Note that I am not sure
|
Get it, will split this pr and submit |
This PR introduces two new interfaces to
Family
:get
andwith_metrics
. These additions cater to the following use cases:get_or_create
interface is used to create metric M1. In crate B, which depends on crate A, there's a need to check if metric A exists (with dynamic labels that may not have been created yet, eg., noset_kv
happened yet). If it exists, additional business-specific labels from crate B can be added to this metric. For example:Family
's definition allows for custom constructors, there are instances where constructor parameters are required. The standardget_or_create
implementation andMetricConstructor
falls short in such scenarios. The newwith_metrics
interface enables users to implement aCustomFamily
that wrapsFamily
as an inner field. By implementingDeref
andDerefMut
,CustomFamily
can reuse most ofFamily
's interfaces while defining its own constructor trait andget_or_create
implementation. This significantly enhances Family's flexibility. For example: