如何从文件更改中热重新加载结构
How to hot reload a struct from file changes
我正在尝试在文件更改时进行热重载,但出现此错误:
期望一个实现 Fn
特性的闭包,但这个闭包只实现了 FnMut
这个闭包实现 FnMut
,而不是 Fn
似乎对我从这个库传递给 new_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(())
}
我在 Rust Discord 初学者聊天中询问,17cupsofcoffee 说我应该使用互斥锁,但我不知道该怎么做。
这里的问题是您在另一个线程中生成此监视函数,并且您可能会在一个线程中写入它而在另一个线程中读取它,从而导致竞争条件。你应该使用一个Mutex
, and lock
it to get a guard that lets you read from it/write to it. Since tide
's global state also needs Clone
, you should also wrap it in an Arc
,一个线程安全的引用计数指针:
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};
// necessary imports
use std::sync::{Arc, Mutex};
const CONFIG_PATH: &str = "config.json";
#[async_std::main]
async fn main() -> tide::Result<()> {
// we store it in an Arc<Mutex<T>>
let config = Arc::new(Mutex::new(load_config(CONFIG_PATH).unwrap()));
let cloned_config = Arc::clone(&config);
let mut watcher: RecommendedWatcher =
Watcher::new_immediate(move |result: Result<Event, Error>| {
let event = result.unwrap();
if event.kind == EventKind::Modify(ModifyKind::Any) {
// we lock the mutex to acquire a mutable guard and write to that
match load_config(CONFIG_PATH) {
Ok(new_config) => *cloned_config.lock().unwrap() = new_config,
Err(error) => println!("Error reloading config: {:?}", error),
}
})?;
watcher.watch(CONFIG_PATH, RecursiveMode::Recursive)?;
let mut app = tide::with_state(config);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
然后,每当需要读取状态时,只需锁定互斥量即可:
let config_guard = req.state().lock().unwrap();
println!("{:?}", config_guard.foo);
额外参考:
我正在尝试在文件更改时进行热重载,但出现此错误:
期望一个实现 Fn
特性的闭包,但这个闭包只实现了 FnMut
这个闭包实现 FnMut
,而不是 Fn
似乎对我从这个库传递给 new_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(())
}
我在 Rust Discord 初学者聊天中询问,17cupsofcoffee 说我应该使用互斥锁,但我不知道该怎么做。
这里的问题是您在另一个线程中生成此监视函数,并且您可能会在一个线程中写入它而在另一个线程中读取它,从而导致竞争条件。你应该使用一个Mutex
, and lock
it to get a guard that lets you read from it/write to it. Since tide
's global state also needs Clone
, you should also wrap it in an Arc
,一个线程安全的引用计数指针:
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};
// necessary imports
use std::sync::{Arc, Mutex};
const CONFIG_PATH: &str = "config.json";
#[async_std::main]
async fn main() -> tide::Result<()> {
// we store it in an Arc<Mutex<T>>
let config = Arc::new(Mutex::new(load_config(CONFIG_PATH).unwrap()));
let cloned_config = Arc::clone(&config);
let mut watcher: RecommendedWatcher =
Watcher::new_immediate(move |result: Result<Event, Error>| {
let event = result.unwrap();
if event.kind == EventKind::Modify(ModifyKind::Any) {
// we lock the mutex to acquire a mutable guard and write to that
match load_config(CONFIG_PATH) {
Ok(new_config) => *cloned_config.lock().unwrap() = new_config,
Err(error) => println!("Error reloading config: {:?}", error),
}
})?;
watcher.watch(CONFIG_PATH, RecursiveMode::Recursive)?;
let mut app = tide::with_state(config);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
然后,每当需要读取状态时,只需锁定互斥量即可:
let config_guard = req.state().lock().unwrap();
println!("{:?}", config_guard.foo);
额外参考: