【问题标题】:Unable to use asynchronous actors无法使用异步演员
【发布时间】:2021-07-14 13:28:36
【问题描述】:

我正在尝试使用actix documentation 中记录的演员。但即使是文档示例也不适合我。我尝试了以下代码,它编译但不打印消息“Received fibo message”

use actix::prelude::*;

// #[derive(Message)]
// #[rtype(Result = "Result<u64, ()>")]
// struct Fibonacci(pub u32);

struct Fibonacci(pub u32);
impl Message for Fibonacci {
    type Result = Result<u64, ()>;
}

struct SyncActor;

impl Actor for SyncActor {
    // It's important to note that you use "SyncContext" here instead of "Context".
    type Context = SyncContext<Self>;
}

impl Handler<Fibonacci> for SyncActor {
    type Result = Result<u64, ()>;

    fn handle(&mut self, msg: Fibonacci, _: &mut Self::Context) -> Self::Result {
        println!("Received fibo message");
        if msg.0 == 0 {
            Err(())
        } else if msg.0 == 1 {
            Ok(1)
        } else {
            let mut i = 0;
            let mut sum = 0;
            let mut last = 0;
            let mut curr = 1;
            while i < msg.0 - 1 {
                sum = last + curr;
                last = curr;
                curr = sum;
                i += 1;
            }
            Ok(sum)
        }
    }
}

fn main() {
    System::new().block_on(async {
        // Start the SyncArbiter with 2 threads, and receive the address of the Actor pool.
        let addr = SyncArbiter::start(2, || SyncActor);

        // send 5 messages
        for n in 5..10 {
            // As there are 2 threads, there are at least 2 messages always being processed
            // concurrently by the SyncActor.
            println!("Sending fibo message");
            addr.do_send(Fibonacci(n));
        }
    });
}

这个程序显示5次:

发送 fibo 消息

两点说明,首先我无法使用宏rtype,我自己用来实现Message。然后addr.do_send(Fibonacci(n)) 行似乎没有向我的演员发送任何内容。但是,如果我使用addr.send(Fibonacci(n)).await;,我的消息会在参与者端发送和接收。但是由于我在等待 send 函数,它同步处理消息,而不是使用我理论上定义的 2 个线程。

我还尝试在主循环之后使用 thread::sleep 等待,但消息也没有到达。

我可能会误解某些东西,但对我来说似乎很奇怪。

Cargo.toml 文件:

[dependencies]
actix = "0.11.1"
actix-rt = "2.2.0"

【问题讨论】:

    标签: rust rust-actix


    【解决方案1】:

    我终于设法让它工作了,虽然我不明白为什么。只需使用 tokio 等待 ctrl-C 就可以让我调用 do_send/try_send 并并行工作。

    fn main() {
        System::new().block_on(async {
            // Start the SyncArbiter with 4 threads, and receive the address of the Actor pool.
            let addr = SyncArbiter::start(4, || SyncActor);
    
            // send 15 messages
            for n in 5..20 {
                // As there are 4 threads, there are at least 4 messages always being processed
                // concurrently by the SyncActor.
                println!("Sending fibo message");
                addr.do_send(Fibonacci(n));
            }
    
    
            // This does not wotk
            //thread::spawn(move || {
            //    thread::sleep(Duration::from_secs_f32(10f32));
            //}).join();
    
            // This made it worked
            tokio::signal::ctrl_c().await.unwrap();
            println!("Ctrl-C received, shutting down");
            System::current().stop();
    
        });
    }
    

    【讨论】:

    猜你喜欢
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 2015-03-28
    相关资源
    最近更新 更多