shekohex / allo-isolate

Run Multithreaded Rust along with Dart VM (in isolate) 🌀

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom types from library result in: `Cell<bool>` cannot be shared between threads safely

JonasHiltl opened this issue · comments

Description:
I'm trying to implement the iota/identity library into flutter+rust. Most of the functions are asynchronous so I'm using allo-isolate. But some custom types of the IOTA library cannot be shared between threads safely.

My async function which mostly uses custom types:

pub async fn create_did_document() -> Result<String> {
    // Generate a new DID Document and public/private key pair.
    // The generated document will have an authentication key associated with
    // the keypair.
    let client = &Client::new().await?;
    let keypair: KeyPair = KeyPair::new_ed25519()?;
    let mut document: IotaDocument = IotaDocument::from_keypair(&keypair)?;

    // Sign the DID Document with the default authentication key.
    document.sign(keypair.secret())?;

    // Use the Client to publish the DID Document to the Tangle.
    document.publish(client).await?;

    println!("DID document: {}", document);
    println!("Transaktion link: {}", document.message_id());
    
    // Return document and keypair.
    Ok(document.to_json().unwrap())
}

Exposing the async create_did_document function:

lazy_static! {
    static ref RUNTIME: io::Result<Runtime> = Builder::new()
        .threaded_scheduler()
        .enable_all()
        .core_threads(4)
        .thread_name("flutterust")
        .build();
}

/// Simple Macro to help getting the value of the runtime.
macro_rules! runtime {
    () => {
        match RUNTIME.as_ref() {
            Ok(rt) => rt,
            Err(_) => {
                return 0;
            }
        }
    };
}

#[no_mangle]
pub extern "C" fn create_did_document(port: i64) -> i32 {
    let rt = runtime!();
    let t = Isolate::new(port).task(iota_did::create_did_document()); // not satisfied
    rt.spawn(t);
    1
}

Full error message:

`Cell<bool>` cannot be shared between threads safely
within `identity_iota::did::doc::iota_document::IotaDocument`, the trait `Sync` is not implemented for `Cell<bool>`
required because it appears within the type `identity_core::crypto::signature::signature::Signature`
required because it appears within the type `Option<identity_core::crypto::signature::signature::Signature>`
required because it appears within the type `identity_did::verifiable::properties::Properties<identity_iota::did::doc::properties::Properties>`
required because it appears within the type `identity_did::document::core_document::CoreDocument<identity_did::verifiable::properties::Properties<identity_iota::did::doc::properties::Properties>>`
required because it appears within the type `identity_iota::did::doc::iota_document::IotaDocument`
required because of the requirements on the impl of `Send` for `&identity_iota::did::doc::iota_document::IotaDocument`
required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, &'r mut identity_iota::did::doc::iota_document::IotaDocument, &identity_iota::tangle::client::Client, identity_iota::tangle::network::Network, Option<&'s identity_iota::tangle::client::Client>, &'t0 identity_iota::tangle::client::Client, &'t1 identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future, (), impl std::future::Future, Result<identity_iota::tangle::client::Client, identity_iota::error::Error>, identity_iota::tangle::client::Client}`
required because it appears within the type `[static generator@identity_iota::did::doc::iota_document::IotaDocument::publish<'_, &identity_iota::tangle::client::Client>::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, &'r mut identity_iota::did::doc::iota_document::IotaDocument, &identity_iota::tangle::client::Client, identity_iota::tangle::network::Network, Option<&'s identity_iota::tangle::client::Client>, &'t0 identity_iota::tangle::client::Client, &'t1 identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future, (), impl std::future::Future, Result<identity_iota::tangle::client::Client, identity_iota::error::Error>, identity_iota::tangle::client::Client}]`
required because it appears within the type `from_generator::GenFuture<[static generator@identity_iota::did::doc::iota_document::IotaDocument::publish<'_, &identity_iota::tangle::client::Client>::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, &'r mut identity_iota::did::doc::iota_document::IotaDocument, &identity_iota::tangle::client::Client, identity_iota::tangle::network::Network, Option<&'s identity_iota::tangle::client::Client>, &'t0 identity_iota::tangle::client::Client, &'t1 identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future, (), impl std::future::Future, Result<identity_iota::tangle::client::Client, identity_iota::error::Error>, identity_iota::tangle::client::Client}]>`
required because it appears within the type `impl std::future::Future`
required because it appears within the type `impl std::future::Future`
required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, impl std::future::Future, (), identity_iota::tangle::client::Client, &'r identity_iota::tangle::client::Client, identity_core::crypto::key::pair::KeyPair, identity_iota::did::doc::iota_document::IotaDocument, &'s mut identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future}`
required because it appears within the type `[static generator@iota_did::create_did_document::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, impl std::future::Future, (), identity_iota::tangle::client::Client, &'r identity_iota::tangle::client::Client, identity_core::crypto::key::pair::KeyPair, identity_iota::did::doc::iota_document::IotaDocument, &'s mut identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future}]`
required because it appears within the type `from_generator::GenFuture<[static generator@iota_did::create_did_document::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, impl std::future::Future, (), identity_iota::tangle::client::Client, &'r identity_iota::tangle::client::Client, identity_core::crypto::key::pair::KeyPair, identity_iota::did::doc::iota_document::IotaDocument, &'s mut identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future}]>`
required because it appears within the type `impl std::future::Future`
required because it appears within the type `impl std::future::Future`

Full Code:
This is the full repo of my project with the corresponding rust implementation of iota-identity. my_project

Yes, that's a constraint for the task that would run, it must be Send + Sync that's how it also required by tokio::spawn and async_std::task::spawn

Closed for inactivity, feel free to ask us to open it again or open a new issue if you still have any questions.