Does actix_web's App::register_data create a single instance or one instance per thread?

余生颓废 提交于 2020-01-26 04:44:31

问题


I am trying to set up a global state for my actix_web::HttpServer, and it seems like register_data is the proper API (I could be wrong).

From the documentation, it is not clear to me how to create a single instance of application data shared by all HttpServer threads. Here is my code piece:

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))
})

In the POST handler my_service, I update the state of MyServer and in the GET handler list_service, it will print out the state.

While my_service is successful in storing the state, the list_service only prints empty output. How do I know if HttpServer created a single instance of MyServer or not? If not, how can I ensure it creates a single instance? The documentation of register_data states:

Application data does not need to be Send or Sync. Internally Data type uses Arc. if your data implements Send + Sync traits you can use web::Data::new() and avoid double Arc.

I'm confused by that. What should the user do so that register_data will register a single instance of the data object? Does this following line in the example from the documentation create a single instance, or one instance per thread?

.register_data(data.clone())

I'm using actix-web 1.0.9.


回答1:


After playing with Rust code a bit more, I understand better now. web::Data is an Arc, hence it's okay to call data.clone() which creates a new instance of Arc but still points to the single shared instance of MyServer. That will allow HttpServer threads to share a global state.

So to fix my problem, I just followed the example in the documentation, i.e, moved the data creation out of HttpServer::new and call clone() inside it:

    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))    
    })


来源:https://stackoverflow.com/questions/59255498/does-actix-webs-appregister-data-create-a-single-instance-or-one-instance-per

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!