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

linera-views: add local variants of store traits #1843

Merged
merged 1 commit into from
Apr 2, 2024

Conversation

Twey
Copy link
Contributor

@Twey Twey commented Mar 28, 2024

Motivation

In order to support non-Send Linera view stores on the Web, we need local variants of the store traits that don't require Send.

Proposal

Replace async-trait with native AFIT, and use trait-variant to automatically create local and non-local variants.

Test Plan

CI build should catch regressions.

Release Plan

  • Need to bump the major/minor version number in the next release of the crates.

This changes the trait interfaces, which is a backward-incompatible change (for people using linera-views directly).

Links

@Twey Twey marked this pull request as draft March 28, 2024 20:25
@Twey Twey force-pushed the 03-28-Local_view_traits branch 7 times, most recently from 70d1e84 to af96fac Compare April 1, 2024 13:14
@Twey Twey marked this pull request as ready for review April 1, 2024 15:01
@Twey Twey requested a review from MathieuDutSik April 1, 2024 15:01
Comment on lines +328 to 338
fn read_value<V: DeserializeOwned>(
&self,
key: &[u8],
) -> impl Future<Output = Result<Option<V>, E>>
where
Self: Sync,
E: From<bcs::Error>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use fn() -> impl Future instead of async fn() here because default implementations of async fn confuse trait_variant, but it seems fine with default implementations of -> impl Trait fns.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to add a comment in the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it should be okay since if someone tries to change this it will fail to compile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(and this applies to several places, so I'd have to copy-paste the comment several times in order to make sure the reader caught it)

Copy link
Contributor

Choose a reason for hiding this comment

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

I think Mathieu Baudet meant adding a TODO(#XXX) that corresponds to considering the resolution of that bug. There are several pending issues here like the confusion of the trait and having a mention could help in dealing with that. The idea is that if something needs you 10 minutes to figure out then a comment is worthwhile.

Copy link
Contributor Author

@Twey Twey Apr 2, 2024

Choose a reason for hiding this comment

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

I didn't add an issue because we're currently blocked on the upstream bug so there's not really much for us TODO — but I've added a comment above the default implementations with a link to the bug to save future readers the time of figuring it out :)

Copy link
Contributor

@MathieuDutSik MathieuDutSik left a comment

Choose a reason for hiding this comment

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

I guess that you need have some code working with non Send stuff. So, you have your reasons. But the works also applies to the Sync trait and it would be nice to mention that.
Also, the boxed() correction is not part of the description of the PR.

Comment on lines +375 to +378
join_all(handles)
.await
.into_iter()
.collect::<Result<_, _>>()
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This (and other small rewrites in this PR) were mandated by Clippy after removing async-trait!

@@ -24,7 +24,7 @@ use aws_sdk_dynamodb::{
Client,
};
use aws_smithy_types::error::operation::BuildError;
use futures::future::join_all;
use futures::future::{join_all, FutureExt as _};
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need the FutureExt as _.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In order to use FutureExt::boxed.

async fn delete_all(config: &Self::Config) -> Result<(), Self::Error> {
for namespace in Self::list_all(config).await? {
Self::delete(config, &namespace).await?;
fn delete_all(config: &Self::Config) -> impl Future<Output = Result<(), Self::Error>> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is that really absolutely needed?
The async fn syntax is familiar and working well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See the comment here — it's because trait-variant gets confused with default implementations of async fns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I would also prefer to keep it as async fn if we could! I think we should undo this change as soon as trait-variant supports default-implemented async fns.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pertinent trait-variant issue: rust-lang/impl-trait-utils#17

@@ -539,6 +538,7 @@ impl DynamoDbStoreInternal {
.expression_attribute_values(":prefix", AttributeValue::B(Blob::new(key_prefix)))
.set_exclusive_start_key(start_key_map)
.send()
.boxed()
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the boxed work independent on the work on LocalKeyValueStore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, I've moved it to #1860 :)

@Twey
Copy link
Contributor Author

Twey commented Apr 2, 2024

the works also applies to the Sync trait and it would be nice to mention that.

I think the original async-trait-based implementation of these traits already assumed that Self: Sync — certainly the implementation needs Self to be Sync in order for the future to be Send. As far as I know, the only change is that the Sync bound is now a constraint on the default function implementation rather than a requirement for the trait itself.

@Twey Twey force-pushed the 03-28-Local_view_traits branch 2 times, most recently from aa025af to 875e14c Compare April 2, 2024 13:26
Copy link
Contributor

@MathieuDutSik MathieuDutSik left a comment

Choose a reason for hiding this comment

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

Thank you for this interesting work.

Comment on lines +328 to 338
fn read_value<V: DeserializeOwned>(
&self,
key: &[u8],
) -> impl Future<Output = Result<Option<V>, E>>
where
Self: Sync,
E: From<bcs::Error>,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think Mathieu Baudet meant adding a TODO(#XXX) that corresponds to considering the resolution of that bug. There are several pending issues here like the confusion of the trait and having a mention could help in dealing with that. The idea is that if something needs you 10 minutes to figure out then a comment is worthwhile.

@Twey Twey merged commit 85502c9 into linera-io:main Apr 2, 2024
5 checks passed
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

3 participants