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

refactor(core/raw): adjust setter methods of AccessorInfo #5244

Closed
wants to merge 5 commits into from

Conversation

koushiro
Copy link
Member

@koushiro koushiro commented Oct 25, 2024

Which issue does this PR close?

No

Rationale for this change

In current usage scenarios, this change will provide a better experience in method chaining,
although it will result in a breaking change.

What changes are included in this PR?

adjust setter methods of AccessorInfo

  • remove:
    • fn full_capability_mut(&mut self) -> &mut Capability
  • add:
    • fn with_full_capability(mut self, capability: Capability) -> Self
  • change:
    • fn set_scheme(&mut self, scheme: Scheme) -> &mut Self => fn with_scheme(mut self, scheme: Scheme) -> Self
    • fn set_root(&mut self, root: &str) -> &mut Self => fn with_root(mut self, root: &str) -> Self
    • fn set_name(&mut self, name: &str) -> &mut Self => fn with_name(mut self, name: &str) -> Self
    • fn set_native_capability(&mut self, capability: Capability) -> &mut Self => fn with_native_capability(mut self, capability: Capability) -> Self

Are there any user-facing changes?

setter methods of AccessorInfo struct

@koushiro koushiro requested a review from Xuanwo as a code owner October 25, 2024 18:17
@koushiro koushiro changed the title refactor(core/raw): adjust builder pattern methods of AccessorInfo refactor(core/raw): adjust setter methods of AccessorInfo Oct 25, 2024
@koushiro koushiro force-pushed the refactor-accessor-info branch from b601a84 to 5e4a516 Compare October 28, 2024 02:50
@Xuanwo
Copy link
Member

Xuanwo commented Oct 31, 2024

  • fn set_scheme(&mut self, scheme: Scheme) -> &mut Self => fn set_scheme(mut self, scheme: Scheme) -> Self
  • fn set_root(&mut self, root: &str) -> &mut Self => fn set_root(mut self, root: &str) -> Self
  • fn set_name(&mut self, name: &str) -> &mut Self => fn set_name(mut self, name: &str) -> Self
  • fn set_native_capability(&mut self, capability: Capability) -> &mut Self => fn set_native_capability(mut self, capability: Capability) -> Self

Hi, this is our API naming style that:

  • fn abc(&self) -> Abc
  • fn set_abc(&mut self, v: Abc) -> &mut Self
  • fn with_abc(mut self, v: Abc) -> Self.

@koushiro
Copy link
Member Author

Hi, this is our API naming style that:

  • fn abc(&self) -> Abc
  • fn set_abc(&mut self, v: Abc) -> &mut Self
  • fn with_abc(mut self, v: Abc) -> Self.

@Xuanwo So do you think this change is ok, except for the API naming style?

@Xuanwo
Copy link
Member

Xuanwo commented Oct 31, 2024

So do you think this change is ok, except for the API naming style?

I believe we only need to add set_full_capability and mark full_capability_mut as deprecated. Other changes seem not needed.

@Xuanwo
Copy link
Member

Xuanwo commented Oct 31, 2024

Hi, sorry for not expressing my idea correctly. Breaking changes like 5fdd515 (#5244) just to alter API naming don't seem good to me.

@Xuanwo
Copy link
Member

Xuanwo commented Oct 31, 2024

In general, we don't want to introduce breaking changes to the API unless there are compelling reasons to do so. For example, such changes might significantly improve our readability, or they might be necessary for implementing certain features.

@koushiro
Copy link
Member Author

In general, we don't want to introduce breaking changes to the API unless there are compelling reasons to do so. For example, such changes might significantly improve our readability, or they might be necessary for implementing certain features.

but for now, AccessorInfo has setter APIs with &mut self as parameter and return &mut Self as return value, IMV, they don't work well with method chaining in current use cases, like below:

  • Before this PR:
    fn info(&self) -> Arc<AccessorInfo> {
        let mut am = AccessorInfo::default();
        am.set_scheme(Scheme::AliyunDrive)
            .set_root(&self.core.root)
            .set_native_capability(Capability {
                stat: true,
                create_dir: true,
                read: true,
                write: true,
                write_can_multi: true,
                // The min multipart size of AliyunDrive is 100 KiB.
                write_multi_min_size: Some(100 * 1024),
                // The max multipart size of AliyunDrive is 5 GiB.
                write_multi_max_size: if cfg!(target_pointer_width = "64") {
                    Some(5 * 1024 * 1024 * 1024)
                } else {
                    Some(usize::MAX)
                },
                delete: true,
                copy: true,
                rename: true,
                list: true,
                list_with_limit: true,

                ..Default::default()
            });
        am.into()
    }
  • After this PR
    fn info(&self) -> Arc<AccessorInfo> {
        AccessorInfo::default()
            .with_scheme(Scheme::AliyunDrive)
            .with_root(&self.core.root)
            .with_native_capability(Capability {
                stat: true,
                create_dir: true,
                read: true,
                write: true,
                write_can_multi: true,
                // The min multipart size of AliyunDrive is 100 KiB.
                write_multi_min_size: Some(100 * 1024),
                // The max multipart size of AliyunDrive is 5 GiB.
                write_multi_max_size: if cfg!(target_pointer_width = "64") {
                    Some(5 * 1024 * 1024 * 1024)
                } else {
                    Some(usize::MAX)
                },
                delete: true,
                copy: true,
                rename: true,
                list: true,
                list_with_limit: true,

                ..Default::default()
            })
            .into()
    }

@Xuanwo
Copy link
Member

Xuanwo commented Oct 31, 2024

IMV, they don't work well with method chaining in current use cases, like below:

It's fine since this API has never been exposed to users. (Please note it's part of the raw API and not our public API surface.)

It's not that bad, right? These APIs are only written once per service and are rarely modified.

Perhaps we can discuss this when we are ready for the OpenDAL core v1.0 release. At this time, introducing breaking changes isn't worth it.


It might be better to initiate a discussion about any API changes before implementing them. I'm glad that someone like you, @koushiro, is willing to take the time to work on this, but we always need to balance the new API changes with the existing API.

@koushiro
Copy link
Member Author

BTW, I found that the API of trait Access is a little different from trait LayeredAccess.
Is this intentional or caused by misaligned changes?

pub trait Access: Send + Sync + Debug + Unpin + 'static {
    fn info(&self) -> Arc<AccessorInfo>;
}

pub trait LayeredAccess: Send + Sync + Debug + Unpin + 'static {
    fn metadata(&self) -> Arc<AccessorInfo> {
        self.inner().info()
    }
}

And the similar inconsistencies exist in the APIs of kv::Adapter and typed_kv::Adapter.

  • kv::Adapter
pub trait Adapter: Send + Sync + Debug + Unpin + 'static {
    /// Return the metadata of this key value accessor.
    fn metadata(&self) -> Metadata;
}

/// Metadata for this key value accessor.
pub struct Metadata {
    scheme: Scheme,
    name: String,
    capabilities: Capability,
}
  • typed_kv::Adapter
pub trait Adapter: Send + Sync + Debug + Unpin + 'static {
    /// Get the scheme and name of current adapter.
    fn info(&self) -> Info;
}

/// Info for this key value accessor.
pub struct Info {
    scheme: Scheme,
    name: String,
    capabilities: Capability,
}

@Xuanwo
Copy link
Member

Xuanwo commented Oct 31, 2024

BTW, I found that the API of trait Access is a little different from trait LayeredAccess. Is this intentional or caused by misaligned changes?

Yes, I believe it's misaligned. We used to use metadata and changed it to info.

And the similar inconsistencies exist in the APIs of kv::Adapter and typed_kv::Adapter.

Keen eyes! They are inconsistent for the same reason. I would appreciate it if you could help fix them.

@Xuanwo
Copy link
Member

Xuanwo commented Nov 12, 2024

Hi, @koushiro. I'm going to close this PR as we don't need it for now. Feel free to propose a discussion if you think there has been a misunderstanding.

@Xuanwo Xuanwo closed this Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants