File 如何从文件更改中热重新加载结构

File 如何从文件更改中热重新加载结构,file,rust,watch,notify,File,Rust,Watch,Notify,我试图在文件更改时进行热重新加载,但出现以下错误: 需要实现Fn特征的闭包,但此闭包仅实现FnMut 此闭包实现的是FnMut,而不是Fn 似乎对我从这个库传递给新的_immediate函数的闭包不满意: notify = { version = "5.0.0-pre.4", features = ["serde"] } 我的代码: use announcer::messages::{load_config, save_config, Config, M

我试图在文件更改时进行热重新加载,但出现以下错误: 需要实现
Fn
特征的闭包,但此闭包仅实现
FnMut
此闭包实现的是
FnMut
,而不是
Fn

似乎对我从这个库传递给新的_immediate函数的闭包不满意:

notify = { version = "5.0.0-pre.4", features = ["serde"] }
我的代码:

use announcer::messages::{load_config, save_config, Config, Message};
use notify::{
    event::ModifyKind, Error, Event, EventFn, EventKind, RecommendedWatcher, RecursiveMode, Watcher,
};
use tide::{http, Body, Response};

const CONFIG_PATH: &str = "config.json";

#[async_std::main]
async fn main() -> tide::Result<()> {
    let mut config = load_config(CONFIG_PATH).unwrap();

    let mut watcher: RecommendedWatcher =
        Watcher::new_immediate(|result: Result<Event, Error>| {
            let event = result.unwrap();
            
            if event.kind == EventKind::Modify(ModifyKind::Any) {
                config = load_config(CONFIG_PATH).unwrap();
            }
        })?;

    watcher.watch(CONFIG_PATH, RecursiveMode::Recursive)?;

    let mut app = tide::with_state(config);
    app.listen("127.0.0.1:8080").await?;

    Ok(())
}
use announcer::messages:{load_config,save_config,config,Message};
使用通知::{
事件::ModifyKind,Error,event,EventFn,EventKind,RecursiveMode,Watcher,
};
使用tide::{http,Body,Response};
const CONFIG_PATH:&str=“CONFIG.json”;
#[async_std::main]
异步fn main()->tide::Result{
让mut config=load_config(config_PATH).unwrap();
让mut观察者:推荐观察者=
观察者:新的即时(|结果:结果|{
let event=result.unwrap();
如果event.kind==EventKind::Modify(ModifyKind::Any){
config=load_config(config_PATH).unwrap();
}
})?;
watcher.watch(配置路径,RecursiveMode::Recursive)?;
让mut-app=tide::带有_状态(config);
应用程序。倾听(“127.0.0.1:8080”)。等待?;
好(())
}

我在Rust Discord初学者聊天中问过,17cupsofcoffee说我应该使用互斥,但我不知道怎么做。

这里的问题是,你在另一个线程中生成了这个监视函数,你可能在一个线程中写入它,而在另一个线程中读取它,从而导致竞争条件。你应该使用,和
来获得一个可以让你读/写的保护。由于
tide
的全局状态也需要
Clone
,因此还应将其包装在线程安全的引用计数指针中:

use announcer::messages:{load_config,save_config,config,Message};
使用通知::{
事件::ModifyKind,Error,event,EventFn,EventKind,RecursiveMode,Watcher,
};
使用tide::{http,Body,Response};
//必要进口
使用std::sync::{Arc,Mutex};
const CONFIG_PATH:&str=“CONFIG.json”;
#[async_std::main]
异步fn main()->tide::Result{
//我们把它储存成一个弧形
让config=Arc::new(Mutex::new(load_config(config_PATH).unwrap());
让clone_config=Arc::clone(&config);
让mut观察者:推荐观察者=
观察者:新的即时(移动|结果:结果|{
let event=result.unwrap();
如果event.kind==EventKind::Modify(ModifyKind::Any){
//我们锁定互斥锁以获得可变保护并写入该保护
匹配加载配置(配置路径){
Ok(新建配置)=>*克隆的配置.lock().unwrap()=新建配置,
Err(error)=>println!(“重新加载配置时出错:{:?}”,error),
}
})?;
watcher.watch(配置路径,RecursiveMode::Recursive)?;
让mut-app=tide::带有_状态(config);
应用程序。倾听(“127.0.0.1:8080”)。等待?;
好(())
}
然后,每当需要读取状态时,只需锁定互斥锁:

let config_guard=req.state().lock().unwrap();
println!(“{:?}”,config_guard.foo);
其他参考:


太棒了,我尝试过这个方法,如果你不经常保存文件,它会起作用。不过我有了圆弧的概念,所以这太棒了!我在库中创建了一个问题,希望找出如何使它可靠。