Skip to content

Commit 04f4740

Browse files
authored
linera-views: make Sync a bound on View, except on the Web (#4060)
## Motivation Currently we have a lot of implementations in `linera-views` that don't work on the Web because they require `Sync` bounds. For example, `MapView` and `QueueView` are not usable on the Web. ## Proposal Conditionally use `trait-variant` to add bounds to the traits themselves rather than the implementations. [Futures should ‘always’ be `Sync`](https://internals.rust-lang.org/t/what-shall-sync-mean-across-an-await/12020/18) anyway. `linera_storage_service::client` contains an implementation of `KeyValueStore` that is not `Sync` even though it isn't on the Web, due to a trait object inside `tonic` that [has](hyperium/tonic#81) [caused](hyperium/tonic#82) [some](hyperium/tonic#84) [contention](hyperium/tonic#117). For that implementation, follow the solution [given there](hyperium/tonic#117 (comment)) and use [`sync_wrapper::SyncFuture`](https://docs.rs/sync_wrapper/latest/sync_wrapper/struct.SyncFuture.html) to make the futures `Sync` based on the fact that they can only be used through `Pin<&mut Self>` anyway. Ditto `aws-smithy-async`. ## Test Plan CI. ## Release Plan - Nothing to do / These changes follow the usual release cycle. ## Links - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent c5e3d9a commit 04f4740

File tree

70 files changed

+226
-208
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+226
-208
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ similar-asserts = "1.5.0"
220220
static_assertions = "1.1.0"
221221
stdext = "0.3.3"
222222
syn = "2.0.52"
223+
sync_wrapper = { version = "1.0.1", features = ["futures"] }
223224
sysinfo = "0.33.1"
224225
tempfile = "3.20.0"
225226
test-case = "3.3.1"

examples/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

linera-storage-service/src/client.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use linera_views::{
2323
AdminKeyValueStore, CommonStoreInternalConfig, ReadableKeyValueStore, WithError,
2424
WritableKeyValueStore,
2525
},
26+
FutureSyncExt,
2627
};
2728
use serde::de::DeserializeOwned;
2829
use tonic::transport::{Channel, Endpoint};
@@ -97,7 +98,7 @@ impl ReadableKeyValueStore for ServiceStoreClientInternal {
9798
let channel = self.channel.clone();
9899
let mut client = StoreProcessorClient::new(channel);
99100
let _guard = self.acquire().await;
100-
let response = client.process_read_value(request).await?;
101+
let response = client.process_read_value(request).make_sync().await?;
101102
let response = response.into_inner();
102103
let ReplyReadValue {
103104
value,
@@ -120,7 +121,7 @@ impl ReadableKeyValueStore for ServiceStoreClientInternal {
120121
let channel = self.channel.clone();
121122
let mut client = StoreProcessorClient::new(channel);
122123
let _guard = self.acquire().await;
123-
let response = client.process_contains_key(request).await?;
124+
let response = client.process_contains_key(request).make_sync().await?;
124125
let response = response.into_inner();
125126
let ReplyContainsKey { test } = response;
126127
Ok(test)
@@ -139,7 +140,7 @@ impl ReadableKeyValueStore for ServiceStoreClientInternal {
139140
let channel = self.channel.clone();
140141
let mut client = StoreProcessorClient::new(channel);
141142
let _guard = self.acquire().await;
142-
let response = client.process_contains_keys(request).await?;
143+
let response = client.process_contains_keys(request).make_sync().await?;
143144
let response = response.into_inner();
144145
let ReplyContainsKeys { tests } = response;
145146
Ok(tests)
@@ -161,7 +162,10 @@ impl ReadableKeyValueStore for ServiceStoreClientInternal {
161162
let channel = self.channel.clone();
162163
let mut client = StoreProcessorClient::new(channel);
163164
let _guard = self.acquire().await;
164-
let response = client.process_read_multi_values(request).await?;
165+
let response = client
166+
.process_read_multi_values(request)
167+
.make_sync()
168+
.await?;
165169
let response = response.into_inner();
166170
let ReplyReadMultiValues {
167171
values,
@@ -193,7 +197,10 @@ impl ReadableKeyValueStore for ServiceStoreClientInternal {
193197
let channel = self.channel.clone();
194198
let mut client = StoreProcessorClient::new(channel);
195199
let _guard = self.acquire().await;
196-
let response = client.process_find_keys_by_prefix(request).await?;
200+
let response = client
201+
.process_find_keys_by_prefix(request)
202+
.make_sync()
203+
.await?;
197204
let response = response.into_inner();
198205
let ReplyFindKeysByPrefix {
199206
keys,
@@ -224,7 +231,10 @@ impl ReadableKeyValueStore for ServiceStoreClientInternal {
224231
let channel = self.channel.clone();
225232
let mut client = StoreProcessorClient::new(channel);
226233
let _guard = self.acquire().await;
227-
let response = client.process_find_key_values_by_prefix(request).await?;
234+
let response = client
235+
.process_find_key_values_by_prefix(request)
236+
.make_sync()
237+
.await?;
228238
let response = response.into_inner();
229239
let ReplyFindKeyValuesByPrefix {
230240
key_values,
@@ -340,7 +350,10 @@ impl ServiceStoreClientInternal {
340350
let channel = self.channel.clone();
341351
let mut client = StoreProcessorClient::new(channel);
342352
let _guard = self.acquire().await;
343-
let _response = client.process_write_batch_extended(request).await?;
353+
let _response = client
354+
.process_write_batch_extended(request)
355+
.make_sync()
356+
.await?;
344357
}
345358
Ok(())
346359
}
@@ -383,7 +396,7 @@ impl ServiceStoreClientInternal {
383396
};
384397
let request = tonic::Request::new(query);
385398
let mut client = StoreProcessorClient::new(channel);
386-
let response = client.process_specific_chunk(request).await?;
399+
let response = client.process_specific_chunk(request).make_sync().await?;
387400
let response = response.into_inner();
388401
let ReplySpecificChunk { chunk } = response;
389402
Ok(chunk)
@@ -458,8 +471,8 @@ impl AdminKeyValueStore for ServiceStoreClientInternal {
458471
async fn list_all(config: &Self::Config) -> Result<Vec<String>, ServiceStoreError> {
459472
let endpoint = config.http_address();
460473
let endpoint = Endpoint::from_shared(endpoint)?;
461-
let mut client = StoreProcessorClient::connect(endpoint).await?;
462-
let response = client.process_list_all(()).await?;
474+
let mut client = StoreProcessorClient::connect(endpoint).make_sync().await?;
475+
let response = client.process_list_all(()).make_sync().await?;
463476
let response = response.into_inner();
464477
let ReplyListAll { namespaces } = response;
465478
let namespaces = namespaces
@@ -478,8 +491,8 @@ impl AdminKeyValueStore for ServiceStoreClientInternal {
478491
let request = tonic::Request::new(query);
479492
let endpoint = config.http_address();
480493
let endpoint = Endpoint::from_shared(endpoint)?;
481-
let mut client = StoreProcessorClient::connect(endpoint).await?;
482-
let response = client.process_list_root_keys(request).await?;
494+
let mut client = StoreProcessorClient::connect(endpoint).make_sync().await?;
495+
let response = client.process_list_root_keys(request).make_sync().await?;
483496
let response = response.into_inner();
484497
let ReplyListRootKeys { root_keys } = response;
485498
Ok(root_keys)
@@ -488,8 +501,8 @@ impl AdminKeyValueStore for ServiceStoreClientInternal {
488501
async fn delete_all(config: &Self::Config) -> Result<(), ServiceStoreError> {
489502
let endpoint = config.http_address();
490503
let endpoint = Endpoint::from_shared(endpoint)?;
491-
let mut client = StoreProcessorClient::connect(endpoint).await?;
492-
let _response = client.process_delete_all(()).await?;
504+
let mut client = StoreProcessorClient::connect(endpoint).make_sync().await?;
505+
let _response = client.process_delete_all(()).make_sync().await?;
493506
Ok(())
494507
}
495508

@@ -499,8 +512,8 @@ impl AdminKeyValueStore for ServiceStoreClientInternal {
499512
let request = tonic::Request::new(query);
500513
let endpoint = config.http_address();
501514
let endpoint = Endpoint::from_shared(endpoint)?;
502-
let mut client = StoreProcessorClient::connect(endpoint).await?;
503-
let response = client.process_exists_namespace(request).await?;
515+
let mut client = StoreProcessorClient::connect(endpoint).make_sync().await?;
516+
let response = client.process_exists_namespace(request).make_sync().await?;
504517
let response = response.into_inner();
505518
let ReplyExistsNamespace { exists } = response;
506519
Ok(exists)
@@ -515,8 +528,8 @@ impl AdminKeyValueStore for ServiceStoreClientInternal {
515528
let request = tonic::Request::new(query);
516529
let endpoint = config.http_address();
517530
let endpoint = Endpoint::from_shared(endpoint)?;
518-
let mut client = StoreProcessorClient::connect(endpoint).await?;
519-
let _response = client.process_create_namespace(request).await?;
531+
let mut client = StoreProcessorClient::connect(endpoint).make_sync().await?;
532+
let _response = client.process_create_namespace(request).make_sync().await?;
520533
Ok(())
521534
}
522535

@@ -526,8 +539,8 @@ impl AdminKeyValueStore for ServiceStoreClientInternal {
526539
let request = tonic::Request::new(query);
527540
let endpoint = config.http_address();
528541
let endpoint = Endpoint::from_shared(endpoint)?;
529-
let mut client = StoreProcessorClient::connect(endpoint).await?;
530-
let _response = client.process_delete_namespace(request).await?;
542+
let mut client = StoreProcessorClient::connect(endpoint).make_sync().await?;
543+
let _response = client.process_delete_namespace(request).make_sync().await?;
531544
Ok(())
532545
}
533546
}

linera-views-derive/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ fn generate_root_view_code(input: ItemStruct) -> TokenStream2 {
217217
impl #impl_generics linera_views::views::RootView for #struct_name #type_generics
218218
where
219219
#(#input_constraints,)*
220-
Self: linera_views::views::View + Sync,
220+
Self: linera_views::views::View,
221221
{
222222
async fn save(&mut self) -> Result<(), linera_views::ViewError> {
223223
use linera_views::{context::Context, batch::Batch, store::WritableKeyValueStore as _, views::View};
@@ -255,7 +255,7 @@ fn generate_hash_view_code(input: ItemStruct) -> TokenStream2 {
255255
where
256256
#(#field_types: linera_views::views::HashableView,)*
257257
#(#input_constraints,)*
258-
Self: linera_views::views::View + Sync,
258+
Self: linera_views::views::View,
259259
{
260260
type Hasher = linera_views::sha3::Sha3_256;
261261

@@ -293,7 +293,7 @@ fn generate_crypto_hash_code(input: ItemStruct) -> TokenStream2 {
293293
where
294294
#(#field_types: linera_views::views::HashableView,)*
295295
#(#input_constraints,)*
296-
Self: linera_views::views::View + Sync,
296+
Self: linera_views::views::View,
297297
{
298298
async fn crypto_hash(&self) -> Result<linera_base::crypto::CryptoHash, linera_views::ViewError> {
299299
use linera_base::crypto::{BcsHashable, CryptoHash};
@@ -353,7 +353,7 @@ fn generate_clonable_view_code(input: ItemStruct) -> TokenStream2 {
353353
where
354354
#(#input_constraints,)*
355355
#(#clone_constraints,)*
356-
Self: linera_views::views::View + Sync,
356+
Self: linera_views::views::View,
357357
{
358358
fn clone_unchecked(&mut self) -> Result<Self, linera_views::ViewError> {
359359
Ok(Self {

linera-views-derive/src/snapshots/linera_views_derive__tests__generate_clonable_view_code-2.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ where
77
MyParam: Send + Sync + 'static,
88
RegisterView<C, usize>: ClonableView,
99
CollectionView<C, usize, RegisterView<C, usize>>: ClonableView,
10-
Self: linera_views::views::View + Sync,
10+
Self: linera_views::views::View,
1111
{
1212
fn clone_unchecked(&mut self) -> Result<Self, linera_views::ViewError> {
1313
Ok(Self {

linera-views-derive/src/snapshots/linera_views_derive__tests__generate_clonable_view_code-3.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ where
1010
usize,
1111
RegisterView<CustomContext, usize>,
1212
>: ClonableView,
13-
Self: linera_views::views::View + Sync,
13+
Self: linera_views::views::View,
1414
{
1515
fn clone_unchecked(&mut self) -> Result<Self, linera_views::ViewError> {
1616
Ok(Self {

linera-views-derive/src/snapshots/linera_views_derive__tests__generate_clonable_view_code-4.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ where
1111
usize,
1212
RegisterView<CustomContext, usize>,
1313
>: ClonableView,
14-
Self: linera_views::views::View + Sync,
14+
Self: linera_views::views::View,
1515
{
1616
fn clone_unchecked(&mut self) -> Result<Self, linera_views::ViewError> {
1717
Ok(Self {

linera-views-derive/src/snapshots/linera_views_derive__tests__generate_clonable_view_code-5.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ where
1010
usize,
1111
RegisterView<custom::path::to::ContextType, usize>,
1212
>: ClonableView,
13-
Self: linera_views::views::View + Sync,
13+
Self: linera_views::views::View,
1414
{
1515
fn clone_unchecked(&mut self) -> Result<Self, linera_views::ViewError> {
1616
Ok(Self {

linera-views-derive/src/snapshots/linera_views_derive__tests__generate_clonable_view_code-6.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ where
1111
usize,
1212
RegisterView<custom::path::to::ContextType, usize>,
1313
>: ClonableView,
14-
Self: linera_views::views::View + Sync,
14+
Self: linera_views::views::View,
1515
{
1616
fn clone_unchecked(&mut self) -> Result<Self, linera_views::ViewError> {
1717
Ok(Self {

0 commit comments

Comments
 (0)