Skip to content

Commit 90b197e

Browse files
committed
add hash checker, remove time locker, remove checker from refresh
1 parent 9bb263d commit 90b197e

4 files changed

Lines changed: 95 additions & 60 deletions

File tree

Cargo.toml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,25 @@ base64_light = "0.1.5"
3636
[profile.dev]
3737
opt-level = 0
3838
debug = true
39+
strip = "none"
40+
debug-assertions = true
41+
overflow-checks = true
42+
lto = false
43+
panic = 'unwind'
44+
incremental = true
45+
codegen-units = 256
46+
rpath = false
3947

4048
[profile.release]
41-
opt-level = 3
49+
opt-level = 'z'
4250
debug = false
4351
lto = true
44-
codegen-units = 1
45-
panic = 'abort'
52+
codegen-units = 24
53+
panic = 'unwind'
54+
strip = true
55+
incremental = true
56+
debug-assertions = false
57+
overflow-checks = false
4658

4759
[profile.test]
4860
opt-level = 0

sss-cli/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,8 @@ utoipa = {workspace = true}
3636
utoipa-scalar = { version = "0.3.0", features = ["axum"] }
3737
## base64
3838
base64_light.workspace = true
39+
sha2 = "0.10.8"
40+
41+
[dependencies.xxhash-rust]
42+
version = "0.8.12"
43+
features = ["xxh3"]

sss-cli/src/tools.rs

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,21 @@ pub async fn refresh_settings(
3131
path: &str,
3232
themes: Option<&Themes>,
3333
layouts: Option<&Layouts>,
34-
) -> Result<SettingsUpdateType> {
34+
) -> Result<()> {
35+
info!("Settings is't actual!");
36+
3537
let mut settings = SSSCliSettings::load(path).await?;
36-
{
37-
let current_settings = SETTINGS.read().await;
38-
if settings == *current_settings {
39-
info!("Nothing to update, settings is actual");
40-
return Ok(SettingsUpdateType::AlreadyActual);
41-
}
42-
}
43-
info!("Settigns is't actual, updating...");
4438
if let Some(themes) = themes {
4539
settings.themes = themes.to_owned()
4640
}
4741
if let Some(layouts) = layouts {
4842
settings.layouts = layouts.to_owned()
4943
}
50-
*SETTINGS.deref().write().await = settings;
44+
{
45+
*SETTINGS.deref().write().await = settings;
46+
}
5147
info!("Settings is actual now!");
52-
Ok(SettingsUpdateType::NotActual)
48+
Ok(())
5349
}
5450
/// Status of actual data
5551
pub enum SettingsUpdateType {
@@ -70,36 +66,33 @@ pub async fn refresh(
7066
) -> Result {
7167
debug!("Themes in cli: {:#?}", &themes);
7268
debug!("Layouts in cli: {:#?}", &layouts);
73-
match refresh_settings(path, themes, layouts).await? {
74-
SettingsUpdateType::AlreadyActual => Ok(()),
75-
SettingsUpdateType::NotActual => {
76-
refresh_html().await?;
77-
tokio::spawn(async move {
78-
if let Err(e) = refresh_png().await {
79-
error!("Got refresh error: {}", e);
80-
}
81-
});
82-
tokio::spawn(async move {
83-
if let Err(e) = refresh_pdf().await {
84-
error!("Got refresh error: {}", e);
85-
}
86-
});
87-
Ok(())
69+
refresh_settings(path, themes, layouts).await?;
70+
refresh_html().await?;
71+
tokio::spawn(async move {
72+
if let Err(e) = refresh_png().await {
73+
error!("Got refresh error: {}", e);
8874
}
89-
}
75+
});
76+
tokio::spawn(async move {
77+
if let Err(e) = refresh_pdf().await {
78+
error!("Got refresh error: {}", e);
79+
}
80+
});
81+
Ok(())
9082
}
9183

9284
#[instrument]
9385
#[inline]
9486
/// Generate final component
9587
pub async fn refresh_html() -> Result {
9688
info!("Render HTML");
97-
let settings = SETTINGS.read().await;
98-
let layout = settings
99-
.layouts
100-
.to_layout(&settings.sss_user_settings, (&settings.themes).into());
101-
102-
*HTML.write().await = layout.finalize()?;
89+
{
90+
let settings = SETTINGS.read().await;
91+
let layout = settings
92+
.layouts
93+
.to_layout(&settings.sss_user_settings, (&settings.themes).into());
94+
*HTML.write().await = layout.finalize()?;
95+
}
10396
info!("Done HTML");
10497
Ok(())
10598
}
@@ -109,9 +102,11 @@ pub async fn refresh_html() -> Result {
109102
/// Generate final component
110103
pub async fn refresh_png() -> Result {
111104
info!("Render PNG");
112-
let html = HTML.read().await;
113-
let image = html_to_image(&html, None, 12).await?;
114-
*PNG.deref().write().await = image;
105+
{
106+
let html = HTML.read().await;
107+
let image = html_to_image(&html, None, 12).await?;
108+
*PNG.deref().write().await = image;
109+
}
115110
info!("Done PNG");
116111
Ok(())
117112
}
@@ -121,9 +116,11 @@ pub async fn refresh_png() -> Result {
121116
/// Generate final component
122117
pub async fn refresh_pdf() -> Result {
123118
info!("Render PDF");
124-
let html = HTML.read().await;
125-
let image = html_to_pdf(&html, None).await?;
126-
*PDF.deref().write().await = image;
119+
{
120+
let html = HTML.read().await;
121+
let image = html_to_pdf(&html, None).await?;
122+
*PDF.deref().write().await = image;
123+
}
127124
info!("Done PDF");
128125
Ok(())
129126
}

sss-cli/src/web/file_watcher.rs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,69 @@
1-
use std::{path::Path, time::Duration};
2-
31
use notify::{recommended_watcher, Event, RecursiveMode, Watcher};
42
use sss_std::{prelude::Layouts, themes::Themes};
3+
use std::path::Path;
54
use tokio::sync::mpsc;
6-
use tracing::{error, info, trace};
5+
use tracing::{debug, error, info, trace};
6+
use xxhash_rust::xxh3::xxh3_64;
77

88
use crate::tools::refresh;
99

10+
// Function to watch a file and refresh settings upon modification
1011
pub async fn check_file_loop(
1112
path: String,
1213
themes: Option<&Themes>,
1314
layouts: Option<&Layouts>,
1415
mut shutdown_rx: tokio::sync::broadcast::Receiver<()>,
1516
) -> anyhow::Result<()> {
16-
let (tx, mut rx) = mpsc::channel(1);
17+
// Create a channel to receive file events
18+
let (tx, mut rx) = mpsc::channel(100);
1719

18-
let p = move |res: Result<Event, notify::Error>| {
20+
// Define a watcher callback
21+
let watcher = move |res: Result<Event, notify::Error>| {
1922
if let Ok(event) = res {
2023
let _ = tx.try_send(event);
2124
}
2225
};
2326

24-
let mut watcher = recommended_watcher(p)?;
27+
// Initialize the file watcher
28+
let mut watcher = recommended_watcher(watcher)?;
2529
watcher.watch(Path::new(&path), RecursiveMode::NonRecursive)?;
2630

27-
info!("Start watching changes for file: {}", &path);
31+
// Read the file content and calculate the initial hash
32+
let file_content = tokio::fs::read(&path).await?;
33+
let mut prevision_processed_hash = calculate_xxhash(&file_content);
34+
drop(file_content);
2835

29-
let mut last_event_time = tokio::time::Instant::now() - Duration::from_millis(1);
36+
info!("Start watching changes for file: {}", &path);
3037

3138
loop {
3239
tokio::select! {
40+
// Receive file events
3341
Some(event) = rx.recv() => {
34-
let now = tokio::time::Instant::now();
35-
if now.duration_since(last_event_time) >= Duration::from_millis(300) {
36-
last_event_time = now;
37-
3842
match event {
3943
Event { kind, .. } if kind.is_modify() => {
40-
trace!("Received modify event");
41-
if let Err(e) = refresh(&path, themes, layouts).await {
42-
error!("Load failed: {}", e);
44+
trace!("Received modify event for {}", path);
45+
// Read the file content
46+
let file_content = tokio::fs::read(&path).await?;
47+
// Calculate the current hash
48+
let current_hash = calculate_xxhash(&file_content);
49+
// Check if the hash has changed
50+
if current_hash != prevision_processed_hash {
51+
debug!("Hash is different:\nprevision: {}\ncurrent: {}", prevision_processed_hash, current_hash);
52+
// Update the hash to the current one
53+
prevision_processed_hash = current_hash;
54+
// Refresh settings
55+
if let Err(e) = refresh(&path, themes, layouts).await {
56+
error!("Failed to refresh settings: {}", e);
57+
}
58+
} else {
59+
info!("Nothing to change");
60+
trace!("Skipped identical update for {}", path);
4361
}
4462
}
4563
_ => (),
4664
}
47-
} else {
48-
trace!("Ignored event due to cooldown");
49-
}
5065
}
66+
// Handle shutdown signal
5167
_ = shutdown_rx.recv() => {
5268
info!("Shutting down file watcher");
5369
break;
@@ -57,3 +73,8 @@ pub async fn check_file_loop(
5773

5874
Ok(())
5975
}
76+
77+
// Function to calculate the xxHash of data
78+
fn calculate_xxhash(data: &[u8]) -> u64 {
79+
xxh3_64(data)
80+
}

0 commit comments

Comments
 (0)