1use std::{
2 path::PathBuf,
3 sync::mpsc::{Receiver, Sender, channel},
4};
5
6use crate::server::{Server, mod_api::ModApi};
7
8use log::error;
9use log::info;
10use log::warn;
11use notify::Watcher;
12
13pub enum ServerUpdate {
14 ModApiChange(ModApi),
15}
16
17struct ServerWorker {
18 mod_api_path: PathBuf,
19 sender: Sender<ServerUpdate>,
20 watcher_recv: Receiver<notify::Result<notify::Event>>,
21}
22
23impl ServerWorker {
24 pub fn new(
25 mod_api_path: PathBuf,
26 sender: Sender<ServerUpdate>,
27 watcher_recv: Receiver<notify::Result<notify::Event>>,
28 ) -> ServerWorker {
29 ServerWorker {
30 mod_api_path,
31 sender,
32 watcher_recv,
33 }
34 }
35
36 pub fn update(&mut self) {
37 let recv = self.watcher_recv.try_recv();
38 if let Ok(notify::Result::Err(err)) = &recv {
39 warn!("What error: {:?}", err);
40 }
41
42 if let Ok(Ok(event)) = recv {
43 if let notify::EventKind::Access(_) = event.kind {
44 } else {
45 if let Ok(json) = std::fs::read_to_string(&self.mod_api_path) {
46 let mod_api: Result<ModApi, serde_json::Error> = serde_json::from_str(&json);
47
48 match mod_api {
49 Ok(mod_api) => {
50 info!("Sending new mod_api: {:?}", mod_api);
51 self.sender
52 .send(ServerUpdate::ModApiChange(mod_api))
53 .unwrap();
54 }
55 Err(err) => {
56 error!("Error deserializing mod_api: {:?}", err);
57 }
58 }
59 }
60 }
61 }
62 }
63}
64
65pub fn spawn_worker(root_path: PathBuf) -> Option<Receiver<ServerUpdate>> {
66 let (send, recv) = channel::<ServerUpdate>();
67
68 let (watch_send, watch_recv) = channel::<notify::Result<notify::Event>>();
69 let mut watcher = notify::recommended_watcher(watch_send).ok()?;
70
71 std::thread::spawn(move || {
72 let mut worker = ServerWorker::new(root_path.join("mod_api.json"), send, watch_recv);
73
74 info!("Initializing worker main loop");
75 loop {
76 while let notify::Result::Err(_) = watcher.watch(
77 &root_path.join("mod_api.json"),
78 notify::RecursiveMode::NonRecursive,
79 ) {}
80 worker.update();
81 }
82 });
83
84 Some(recv)
85}
86
87impl Server {
88 pub fn handle_worker_messages(&mut self) {
89 if let Ok(message) = self.messages_chan.try_recv() {
90 match message {
91 ServerUpdate::ModApiChange(mod_api) => {
92 info!("New mod_api: {:?}", mod_api);
93 self.mod_api = mod_api;
94 }
95 }
96 }
97 }
98}