如何为Hyper处理程序共享可变状态?

Ron*_*ith 4 rust

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

此页面已被要求$ 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();

}
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 11

由于请求处理可能发生在不同的线程中,因此您需要同步对全局状态的访问,您需要使用以下内容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();
Run Code Online (Sandbox Code Playgroud)

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

  • 顺便说一句:如果它是一个简单的计数器,也可以使用一种"原子*"类型,将签名更改为"问候(&self,Request,Response)",并通过`fetch_add`递增计数器. (2认同)