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

Possibly unnecessary Sync #70

Closed
jokil123 opened this issue Feb 6, 2023 · 3 comments
Closed

Possibly unnecessary Sync #70

jokil123 opened this issue Feb 6, 2023 · 3 comments

Comments

@jokil123
Copy link
Contributor

jokil123 commented Feb 6, 2023

The following code:

use std::io::Read;

use firestore::{FirestoreDb, FirestoreListenerTarget};
use tower_controller_rs::temp_file_token_storage::TempFileTokenStorage;

#[tokio::main]
async fn main() {
    let db = FirestoreDb::new("my-project-id").await.unwrap();

    let mut listener = db.create_listener(TempFileTokenStorage).await.unwrap();

    db.fluent()
        .select()
        .from("my-col")
        .listen()
        .add_target(FirestoreListenerTarget::new(1), &mut listener)
        .unwrap();

    listener
        .start(move |r| {
            let db = db.clone();
            async move {
                db.fluent()
                    .select()
                    .by_id_in("mycol")
                    .one("mydoc")
                    .await
                    .unwrap();
                Ok(())
            }
        })
        .await
        .unwrap();

    std::io::stdin().read(&mut [1]).unwrap();

    listener.shutdown().await.unwrap();
}

Fails to compile with the following error:

error: future cannot be shared between threads safely
   --> src\bin\error_example.rs:20:10
    |
20  |         .start(move |r| {
    |          ^^^^^ future created by async block is not `Sync`
    |
    = help: the trait `Sync` is not implemented for `dyn Future<Output = Result<gcloud_sdk::apis::google::firestore::v1::Document, FirestoreError>> + Send`
note: future is not `Sync` as this value is used across an await
   --> D:\Repos\firestore-rs\src\fluent_api\select_builder.rs:330:17
    |
322 |               match self
    |  ___________________-
323 | |                 .db
324 | |                 .get_doc_at::<S>(
325 | |                     parent.as_str(),
...   |
328 | |                     self.return_only_fields,
329 | |                 )
    | |_________________- has type `Pin<Box<dyn Future<Output = Result<gcloud_sdk::apis::google::firestore::v1::Document, FirestoreError>> + Send>>` which is not `Sync`
330 |                   .await
    |                   ^^^^^^ await occurs here, with the value maybe used later
...
338 |           } else {
    |           - the value is later dropped here
note: required by a bound in `FirestoreListener::<D, S>::start`
   --> D:\Repos\firestore-rs\src\db\listen_changes.rs:231:57
    |
231 |         F: Future<Output = BoxedErrResult<()>> + Send + Sync + 'static,
    |                                                         ^^^^ required by this bound in `FirestoreListener::<D, S>::start`

This is due to the start function requiring a Sync future and the fluent api not returning a future with Sync. It is possible to remove this requirement from the start function (and a function it calls) without it causing an error. Not guaranteed everything still works. I will open a draft pull request (#71 ).

@abdolence
Copy link
Owner

Hmm, interesting. It is possibly easier to just propagate db instances to the async function as additional argument - maybe useful for many cases.

@abdolence
Copy link
Owner

This is maybe more convenient for people in general:
#73

@abdolence
Copy link
Owner

Still considering if #73 is needed or not. Until then I've released your fix in 0.26.2. Thanks for the PR!

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

No branches or pull requests

2 participants