Обработка общего состояния между actix и параллельным потоком

Чтобы изучить ржавчину и параллелизм, я пытаюсь поделиться общей хэш-картой между веб-сервером actix и параллельным потоком.

  • Есть один поток, который обновляет хэш-карту с текущей меткой времени каждые 10 секунд.
  • есть GET API, который возвращает последнюю временную метку, указанную в хэш-карте

вот мой код

use actix_web::{web, App, HttpServer};
use std::collections::HashMap;
use chrono::prelude::*;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

async fn get_latest_timestamp(data: web::Data<Arc<Mutex<HashMap<String, String>>>>) -> String {
    
    let wrapped_data = data.lock().unwrap();

    match wrapped_data.get("time_now") {
        Some(i) => String::from(i),
        None => String::from("None")
    }
}

fn update_timestamps(data: Arc<Mutex<HashMap<String, String>>>) -> () {

    loop {
        thread::sleep(Duration::from_secs(10));
        println!("Updating time.... ");
        let now: DateTime<Local> = Local::now();

        let mut data = data.lock().unwrap();
    
        data.insert(String::from("time_now"), now.to_rfc2822());
    }
}


#[actix_web::main]
async fn main() -> std::io::Result<()> {

    let mut hash = HashMap::new();
    hash.insert(String::from("time_now"), Local::now().to_rfc2822());

    let data = Arc::new(Mutex::new(hash));

    let hash_clone = Arc::clone(&data);
    thread::spawn(move || {
        update_timestamps(hash_clone)
    });

    HttpServer::new( move || {
        App::new()
            .data(data.clone())
            .route("/", web::get().to(get_latest_timestamp))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Есть ли что-нибудь, что я мог бы сделать лучше? У меня есть пара вопросов

  1. Как вообще обрабатывать ошибки, возникающие в параллельном потоке? основной поток каким-то образом уведомлен?

  2. код в update_timestamps работает в непрерывном цикле — есть ли лучший способ справиться с этим, чтобы он полностью завершился?

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *