title: Rust tokio: Awaiting an async function in spawned thread
body: <p>Trying to call an async-function inside a new tokio thread results in an error for some functions.</p>
  <p>In this minimal example, crates tokio and iota-streams are used. Method send_announce() is async and returns an Address. Awaiting this method results in a compile error, stating that std::Marker::Send trait is not implemented for</p>
  <pre><code>dyn std::future::Future&lt;Output = Result&lt;GenericMessage&lt;TangleAddress, BinaryBody&gt;, iota_streams::iota_streams_core::Error&gt;&gt;
  dyn std::future::Future&lt;Output = Result&lt;(), iota_streams::iota_streams_core::Error&gt;&gt;
  dyn std::future::Future&lt;Output = Result&lt;&amp;mut iota_streams::iota_streams_ddml::command::sizeof::Context&lt;KeccakF1600&gt;, iota_streams::iota_streams_core::Error&gt;&gt;
  dyn std::future::Future&lt;Output = Result&lt;&amp;mut iota_streams::iota_streams_ddml::command::wrap::Context&lt;KeccakF1600, &amp;mut [u8]&gt;, iota_streams::iota_streams_core::Error&gt;&gt;
  </code></pre>
  <p>As for my understanding, the problem is the lack of one or more Sync/Send trait implementations and to be able to pass data between threads Rust needs the whole chain to have Sync and Send implemented.</p>
  <p>The documentation states that the mentioned structs have Sync and Send as auto traits implemented: (iota_streams_core::Error, wrap::Context, TangleAddress, BinaryBody, command::sizeof::Context, KeccakF1600 ...)</p>
  <p>Calling the same functions inside the main thread works fine.</p>
  <p>I tried wrapping the resulting future from send_announce() into a Box, implementing the Send trait unsafe and wrapping the response into a struct ..., without changing the compile error.</p>
  <p>It seems that the dynamic future response is somehow problematic in this context. I'm new to rust and would appreciate every help or idea I can get on how to solve this problem. Is this approach even possible?</p>
  <p>My program should be invoked by a call and handle the request in a separate thread. Inside this thread for e.g. this announcement link is generated.</p>
  <p>The example shown is a minimal example to reduce the issue to the important parts.
  Tested on Ubuntu with rust-stable and nightly.</p>
  <pre><code>// main.rs
  use iota_streams::{
      app::transport::tangle::client::Client,
      app_channels::api::tangle::{Author, ChannelType},
      core::Result,
  };
  use rand::Rng;
  
  #[tokio::main]
  async fn main() -&gt; Result&lt;()&gt; {
      //
      // This works fine
      //
      let seed = generate_seed();
      let client = Client::new_from_url(&quot;https://chrysalis-nodes.iota.org&quot;);
      let mut author = Author::new(&amp;seed, ChannelType::SingleBranch, client.clone());
      //
      // No error occurs here
      //
      let announcement_link = author.send_announce().await?;
      //
      // Spawn new thread
      //
      tokio::spawn(async move {
          let seed = generate_seed();
          let client = Client::new_from_url(&quot;https://chrysalis-nodes.iota.org&quot;);
          //
          // Error occurs here
          //
          let announcement_link = author.send_announce().await?;
          Ok(())
      });
  
      Ok(())
  }
  // Make a seed
  const ALPH9: &amp;str = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ9&quot;;
  fn generate_seed() -&gt; String {
      let seed: String = (0..81)
          .map(|_| { ALPH9
                  .chars().nth(rand::thread_rng().gen_range(0..27)).unwrap()
          }).collect::&lt;String&gt;();
      seed
  }
  </code></pre>
  <pre><code># Cargo.toml
  [package]
  name = &quot;example&quot;
  version = &quot;0.1.0&quot;
  edition = &quot;2021&quot;
  
  [dependencies]
  iota-streams = { git = &quot;https://github.com/iotaledger/streams&quot;, branch  = &quot;develop&quot;}
  tokio = { version = &quot;1.17.0&quot;, features = [&quot;full&quot;] }
  rand = &quot;0.8.5&quot;
  </code></pre>
  <pre><code>error: generator cannot be sent between threads safely
     --&gt; src/main.rs:17:5
      |
  17  |     tokio::spawn(async {
      |     ^^^^^^^^^^^^ future created by async block is not `Send`
      |
      = help: the trait `std::marker::Send` is not implemented for `dyn std::future::Future&lt;Output = Result&lt;GenericMessage&lt;TangleAddress, BinaryBody&gt;, iota_streams::iota_streams_core::Error&gt;&gt;`
  note: required by a bound in `tokio::spawn`
     --&gt; /home/-/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/task/spawn.rs:127:21
      |
  127 |         T: Future + Send + 'static,
      |                     ^^^^ required by this bound in `tokio::spawn`
  
  error: generator cannot be sent between threads safely
     --&gt; src/main.rs:17:5
      |
  17  |     tokio::spawn(async {
      |     ^^^^^^^^^^^^ future created by async block is not `Send`
      |
      = help: the trait `std::marker::Send` is not implemented for `dyn std::future::Future&lt;Output = Result&lt;(), iota_streams::iota_streams_core::Error&gt;&gt;`
  note: required by a bound in `tokio::spawn`
     --&gt; /home/-/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/task/spawn.rs:127:21
      |
  127 |         T: Future + Send + 'static,
      |                     ^^^^ required by this bound in `tokio::spawn`
  
  error: generator cannot be sent between threads safely
     --&gt; src/main.rs:17:5
      |
  17  |     tokio::spawn(async {
      |     ^^^^^^^^^^^^ future created by async block is not `Send`
      |
      = help: the trait `std::marker::Send` is not implemented for `dyn std::future::Future&lt;Output = Result&lt;&amp;mut iota_streams::iota_streams_ddml::command::sizeof::Context&lt;KeccakF1600&gt;, iota_streams::iota_streams_core::Error&gt;&gt;`
  note: required by a bound in `tokio::spawn`
     --&gt; /home/-/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/task/spawn.rs:127:21
      |
  127 |         T: Future + Send + 'static,
      |                     ^^^^ required by this bound in `tokio::spawn`
  
  error: generator cannot be sent between threads safely
     --&gt; src/main.rs:17:5
      |
  17  |     tokio::spawn(async {
      |     ^^^^^^^^^^^^ future created by async block is not `Send`
      |
      = help: the trait `std::marker::Send` is not implemented for `dyn std::future::Future&lt;Output = Result&lt;&amp;mut iota_streams::iota_streams_ddml::command::wrap::Context&lt;KeccakF1600, &amp;mut [u8]&gt;, iota_streams::iota_streams_core::Error&gt;&gt;`
  note: required by a bound in `tokio::spawn`
     --&gt; /home/-/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/task/spawn.rs:127:21
      |
  127 |         T: Future + Send + 'static,
      |                     ^^^^ required by this bound in `tokio::spawn`
  
  error: could not compile `teststh` due to 4 previous errors
  </code></pre>