-
Notifications
You must be signed in to change notification settings - Fork 881
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: implement GetOptions extensions #7160
Conversation
By the way, it's worth mentioning that I based this PR on the tag for the Also worth noting that this is a draft PR for now because I still need to test it out in https://github.com/influxdata/influxdb, write better docstrings, and run the approach by @crepererum and @tustvold before spending too much additional time on it. |
I would prefer if we don't use trait Extension: std::fmt::Debug {
fn as_any(&self) -> &dyn std::any::Any;
fn partial_eq(&self, other: &dyn std::any::Any) -> bool;
}
#[derive(Debug, PartialEq)]
struct MyExt {
x: u8,
}
impl Extension for MyExt {
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn partial_eq(&self, other: &dyn std::any::Any) -> bool {
other
.downcast_ref::<Self>()
.map(|other| other.partial_eq(self))
.unwrap_or_default()
}
} |
41ca3a4
to
ed3816a
Compare
// this is necessary because ExtWrapper is a generic impl of Extensions necessary for | ||
// converting from external Arc<dyn Any ...> types where none of the trait bounts can | ||
// implement PartialEq due to dyn-compatibility requirements. | ||
true |
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.
@crepererum I don't know if this violates the spirit of your preference for making Extension
trait implementations also implement PartialEq
and Debug
, but this was the best I could come up with that would allow me to build a Extensions
instance from a HashMap<TypeId, Arc<dyn Any + Send + Sync + 'static>>
. I should have a PR up shortly demonstrating the use of this in datafusion.
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.
Here's the PR I mentioned that demonstrates what I had in mind with respect to how to use this: https://github.com/apache/datafusion/pull/14805/files#diff-cd6fee4ac01d3e6f21ca25e40cbaf9a462882eca8ed80d7868079327a9ce31a9R576
I'll test this out in https://github.com/influxdata/influxdb tomorrow to see if I can get the tracing spans I wanted in our caching object store implementation.
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 think this wrapper is flawed. People should implement the trait themselves or -- if they cannot due to the orphan rule -- create a dedicated wrapper type for whatever they need.
ed3816a
to
3c4a843
Compare
b5147e9
to
167afbb
Compare
}; | ||
|
||
/// Trait that must be implemented by extensions. | ||
pub trait Extension: std::fmt::Debug + Send + Sync { |
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.
Hi, I'm concerned about adding such an API in object_store
, especially a model tailored for specific use cases like metrics and tracing.
Have we considered adding a TracingObjectStore
that wraps another object store and adds traces for every API call? I think this approach is more extensible and can help avoid making changes for every action.
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.
We have discussed that possibility, but it's not straightforward to do without non-trivial refactors in InfluxDB. And even if we did that, the tracing spans would not be properly parented within the hierarchy of tracing spans -- the best we would be able to do is get them parented at the root-span of a given query (as opposed to under the most recently-created descendant of that root span).
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.
For what it's worth, another use case aside from tracing spans that @crepererum mentioned to me was passing file size hints via GetOptions
to a caching layer to avoid extraneous HEAD
requests in certain use cases.
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.
Hi, I'm concerned about adding such an API in
object_store
, especially a model tailored for specific use cases like metrics and tracing.
What exactly does concern you?
Have we considered adding a
TracingObjectStore
that wraps another object store and adds traces for every API call? I think this approach is more extensible and can help avoid making changes for every action.
That assumes that you have one single ObjectStore
. Truth is, ObjectStore
is an abstract interface that lends itself to dynamic composition, e.g. to add caching as wrappers.
I wonder if supporting PartialEq for extensions is all that important, my understanding is the PartialEq support is a utility for testing. As such I wonder if we just return IMO it would be nice if we didn't have to export an Extension trait publicly and could just support registering anything |
Fair, I'm not dying on that hill. |
That can actually be done, but requires some more cleverness. I'll give it a shot. |
I've hacked together an alternative implementation at #7170 which -- I think -- has a reasonable interface. |
Which issue does this PR close?
Closes #7155
Rationale for this change
This is laid out in the associated issue.
What changes are included in this PR?
object_store::Extensions
HashMap<TypeId, Arc<dyn Any + Send + Sync + 'static>>
Extensions
instance once rather than on everyObjectStore
method call where one is needed.extensions: Extensions
field toGetOptions
PutOptions
as well, but I'm personally less interested in that so I'm leaving it out for now.Are there any user-facing changes?
Yes, the new field in
GetOptions
and a new publicly-exposed type,object_store::Extensions
.