Emulator000 / telegram-bot

Rust Library for creating a Telegram Bot
MIT License
15 stars 6 forks source link

How do I use this crate with tokio? #7

Open fin-ger opened 6 years ago

fin-ger commented 6 years ago

I am currently struggling to get a Future of this crate resolved in a tokio::spawn or even tokio::run. The only thing that is working (but not fitting for me) is the current_thread runtime from the examples. This is the code I am using:

extern crate tokio;
extern crate telegram_bot_fork;
extern crate futures;

use std::{thread, time, env};
use telegram_bot_fork::*;
use futures::{Stream, Future, future::lazy};

fn main() {
    tokio::run(lazy(|| {
        tokio::spawn(lazy(|| {
            let token = env::var("TELEGRAM_BOT_TOKEN").unwrap();
            let api = Api::new(token).unwrap();

            api.stream().for_each(move |update| {
                // if the received update contains a new message...
                if let UpdateKind::Message(message) = update.kind {
                    if let MessageKind::Text { ref data, .. } = message.kind {
                        api.spawn(message.text_reply("this is a test"));
                    }
                }

                Ok(())
            }).map_err(|_| ())
        }));

        loop {
            thread::sleep(time::Duration::from_secs(5));
            println!("Application running...");
        }
    }));
}

This is the compile error I get:

$ cargo run                                                                                                                            101 ↵
   Compiling telegram-test v0.1.0 (/home/fin/Development/github/telegram-test)
error[E0277]: `std::rc::Rc<telegram_bot_fork::api::ApiInner>` cannot be sent between threads safely
  --> src/main.rs:12:9
   |
12 |         tokio::spawn(lazy(|| {
   |         ^^^^^^^^^^^^ `std::rc::Rc<telegram_bot_fork::api::ApiInner>` cannot be sent between threads safely
   |
   = help: within `futures::Lazy<[closure@src/main.rs:12:27: 26:10], futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<telegram_bot_fork::api::ApiInner>`
   = note: required because it appears within the type `telegram_bot_fork::Api`
   = note: required because it appears within the type `telegram_bot_fork::UpdatesStream`
   = note: required because it appears within the type `futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>`
   = note: required because it appears within the type `futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>`
   = note: required because it appears within the type `futures::future::lazy::_Lazy<[closure@src/main.rs:12:27: 26:10], futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>>`
   = note: required because it appears within the type `futures::Lazy<[closure@src/main.rs:12:27: 26:10], futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>>`
   = note: required by `tokio::spawn`

error[E0277]: `(dyn futures::Future<Error=telegram_bot_fork::Error, Item=std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>> + 'static)` cannot be sent between threads safely
  --> src/main.rs:12:9
   |
12 |         tokio::spawn(lazy(|| {
   |         ^^^^^^^^^^^^ `(dyn futures::Future<Error=telegram_bot_fork::Error, Item=std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>> + 'static)` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn futures::Future<Error=telegram_bot_fork::Error, Item=std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>> + 'static)`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn futures::Future<Error=telegram_bot_fork::Error, Item=std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>> + 'static)>`
   = note: required because it appears within the type `std::boxed::Box<(dyn futures::Future<Error=telegram_bot_fork::Error, Item=std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>> + 'static)>`
   = note: required because it appears within the type `telegram_bot_fork::TelegramFuture<std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>>`
   = note: required because it appears within the type `std::option::Option<telegram_bot_fork::TelegramFuture<std::option::Option<std::vec::Vec<telegram_bot_fork::Update>>>>`
   = note: required because it appears within the type `telegram_bot_fork::UpdatesStream`
   = note: required because it appears within the type `futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>`
   = note: required because it appears within the type `futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>`
   = note: required because it appears within the type `futures::future::lazy::_Lazy<[closure@src/main.rs:12:27: 26:10], futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>>`
   = note: required because it appears within the type `futures::Lazy<[closure@src/main.rs:12:27: 26:10], futures::MapErr<futures::stream::ForEach<telegram_bot_fork::UpdatesStream, [closure@src/main.rs:16:35: 25:14 api:_], std::result::Result<(), telegram_bot_fork::Error>>, [closure@src/main.rs:25:24: 25:30]>>`
   = note: required by `tokio::spawn`

error: aborting due to 2 previous errors

How do I use the telegram-bot API with tokio?

ark0f commented 6 years ago

Please, read examples carefully. You need to use tokio::runtime::current_thread::Runtime instead of tokio::runtime::Runtime.

@Emulator000, what do you think about adding multithreading?

Emulator000 commented 6 years ago

@ark0f it's a feature that I want to implement but we must be careful with performances, using Arc and Mutex is certainly slower than Rc and RefCell.

fin-ger commented 6 years ago

Is there a reason that we need a mutex? Isnt an RwLock enough? (locked vs. unlocked read)