【问题标题】:How to share mutable state for a Hyper handler?如何为 Hyper 处理程序共享可变状态?
【发布时间】:2016-02-28 03:13:01
【问题描述】:

作为一个非常简单的例子,我正在尝试编写一个简单回复的网络服务器

此页面已被请求 $N 次

但是我在共享可变状态以实现这一点时遇到了很多麻烦。这是我最好的尝试:

extern crate hyper;

use hyper::Server;
use hyper::server::Request;
use hyper::server::Response;

struct World {
    count: i64,
}

impl World {
    fn greet(&mut self, req: Request, res: Response) {
        self.count += 1;
        let str: String = format!("this page has been requested {} times", self.count);
        res.send(str.as_bytes()).unwrap();
    }
}

fn main() {
    println!("Started..");

    let mut w = World { count: 0 }; 

    Server::http("127.0.0.1:3001").unwrap()
        .handle(move |req: Request, res: Response| w.greet(req, res) ).unwrap();

}

【问题讨论】:

    标签: rust


    【解决方案1】:

    因为请求处理可能发生在不同的线程中,所以需要同步访问全局状态,为此需要使用Mutex之类的东西:

    let w = Mutex::new(World { count: 0 });
    
    Server::http("127.0.0.1:3001").unwrap()
        .handle(move |req: Request, res: Response| w.lock().unwrap().greet(req, res))
        .unwrap();
    

    您可以从Server::handle() 的签名中找到这一点:它要求其处理程序为Handler + 'static,而Handler 本身需要Send + Sync。因此,这个闭包捕获的所有内容也必须是'static + Send + Sync,即可以安全地从多个线程访问。封装到互斥体中的值通常满足这些要求(当然,如果它们不包含引用)。

    【讨论】:

    • 顺便说一句:如果是简单的计数器,也可以使用Atomic*类型之一,将签名更改为greet(&self, Request, Response),并通过fetch_add递增计数器。
    • 我认为这个答案已经过时了。请问有机会更新吗?
    猜你喜欢
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2016-11-02
    相关资源
    最近更新 更多