0

我正在尝试为我的 设置一个全局状态actix_web::HttpServer,这似乎register_data是正确的 API(我可能是错的)。

文档中,我不清楚如何创建由所有HttpServer线程共享的应用程序数据的单个实例。这是我的代码片段:

HttpServer::new(|| {
    App::new()
        .register_data(web::Data::new(Mutex::new(MyServer::new())))
        .service(web::resource("/myservice").route(web::post().to(my_service)))
        .service(web::resource("/list").to(list_service))
})

在 POST 处理程序my_service中,我更新了状态,MyServer在 GET 处理程序list_service中,它将打印出状态。

虽然my_service存储状态成功,但list_service仅打印空输出。我如何知道是否HttpServer创建了单个实例MyServer?如果没有,我如何确保它创建一个实例?国家的文件register_data

应用程序数据不需要是SendSync。内部Data类型使用Arc. 如果您的数据实现Send+Sync特征,您可以使用web::Data::new()并避免使用 double Arc

我对此感到困惑。用户应该怎么做register_data才能注册数据对象的单个实例?文档示例中的以下行是创建一个实例,还是每个线程创建一个实例?

.register_data(data.clone())

我正在使用actix-web 1.0.9。

4

1 回答 1

1

在玩了更多 Rust 代码之后,我现在理解得更好了。web::Data是一个Arc,因此可以调用data.clone()which 创建 的新实例Arc但仍指向 的单个共享实例MyServer。这将允许HttpServer线程共享全局状态。

因此,为了解决我的问题,我只是按照文档中的示例进行操作,即将数据创建移出HttpServer::new并在其中调用clone()

    let my_data = web::Data::new(Mutex::new(MyServer::new()));
    HttpServer::new(move || {
        App::new()
            .register_data(my_data.clone())  // only Arc is cloned
            .service(web::resource("/myservice").route(web::post().to(my_service)))
            .service(web::resource("/list").to(list_service))    
    })
于 2019-12-10T00:35:56.657 回答