diff --git a/.env b/.env new file mode 100644 index 0000000..4590401 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +CLIENT_GRAPH_STEPS=150 +CLIENT_PORT=3000 +CLIENT_REFETCH_INTERVAL=500 +SERVER_ACTIVE_WINDOW=5000 +SERVER_PORT=3001 +SERVER_REFRESH_INTERVAL=500 \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index c257fbb..6864200 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,6 +198,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "either" version = "1.8.1" @@ -792,6 +798,7 @@ name = "stats_server" version = "0.1.0" dependencies = [ "axum", + "dotenv", "serde_json", "sysinfo", "tokio", diff --git a/Cargo.toml b/Cargo.toml index ee8f2f5..605fb83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] axum = { version = "0.6.9", features = ["macros", "ws"] } +dotenv = "0.15.0" serde_json = "1.0.93" sysinfo = "0.30.11" tokio = { version = "1.25.0", features = ["full"] } @@ -14,4 +15,4 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } [[bin]] name = "stats_server" -path = "src/stats-server/main.rs" \ No newline at end of file +path = "src/stats-server/main.rs" diff --git a/package.json b/package.json index 43dae7a..bfe7eb4 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite --host & cargo run", + "dev": "vite --port $CLIENT_PORT --host & cargo run", "build": "tsc && vite build && cargo build --release", - "preview": "vite preview --host & cargo run --release" + "preview": "vite --port $CLIENT_PORT preview --host & cargo run --release" }, "dependencies": { "@tanstack/react-query": "^5.32.0", diff --git a/src/client/App.tsx b/src/client/App.tsx index 7263508..c83fe45 100644 --- a/src/client/App.tsx +++ b/src/client/App.tsx @@ -19,7 +19,7 @@ const Main = () => { const dynamicQuery = useQuery({ queryKey: ['dynamic'], queryFn: fetchDynamicData, - refetchInterval: 500, + refetchInterval: Number(import.meta.env.CLIENT_REFETCH_INTERVAL), }); const isLoading = staticQuery.isLoading || dynamicQuery.isLoading; diff --git a/src/client/api.ts b/src/client/api/index.ts similarity index 91% rename from src/client/api.ts rename to src/client/api/index.ts index 5f0daa4..d51c4ba 100644 --- a/src/client/api.ts +++ b/src/client/api/index.ts @@ -1,6 +1,6 @@ const getApiUrl = (path: string) => { const url = new URL(window.location.href); - url.port = '3001'; + url.port = import.meta.env.SERVER_PORT; url.pathname = path; return url; diff --git a/src/client/types.ts b/src/client/api/types.ts similarity index 100% rename from src/client/types.ts rename to src/client/api/types.ts diff --git a/src/client/components/chart-cards/cpu.tsx b/src/client/components/chart-cards/cpu.tsx index df849b7..1bd44ec 100644 --- a/src/client/components/chart-cards/cpu.tsx +++ b/src/client/components/chart-cards/cpu.tsx @@ -5,7 +5,7 @@ import { ChartCard } from './index'; export const Cpu = () => { const { data: staticData } = useQuery({ queryKey: ['static'] }); const { data: dynamicData } = useQuery({ queryKey: ['dynamic'] }); - const [history, setHistory] = useState(new Array(150).fill([])); + const [history, setHistory] = useState(new Array(Number(import.meta.env.CLIENT_GRAPH_STEPS)).fill([])); useEffect(() => { if (dynamicData) { diff --git a/src/client/components/chart-cards/disks.tsx b/src/client/components/chart-cards/disks.tsx index 1689a51..035b373 100644 --- a/src/client/components/chart-cards/disks.tsx +++ b/src/client/components/chart-cards/disks.tsx @@ -4,7 +4,7 @@ import { ChartCard } from './index'; export const Disks = () => { const { data: dynamicData } = useQuery({ queryKey: ['dynamic'] }); - const [history, setHistory] = useState(new Array(150).fill([])); + const [history, setHistory] = useState(new Array(Number(import.meta.env.CLIENT_GRAPH_STEPS)).fill([])); useEffect(() => { if (dynamicData) { diff --git a/src/client/components/chart-cards/memory.tsx b/src/client/components/chart-cards/memory.tsx index 8ed5cf0..297c5fc 100644 --- a/src/client/components/chart-cards/memory.tsx +++ b/src/client/components/chart-cards/memory.tsx @@ -8,7 +8,7 @@ const formatOptions = { units: 'B' }; export const Memory = () => { const { data: staticData } = useQuery({ queryKey: ['static'] }); const { data: dynamicData } = useQuery({ queryKey: ['dynamic'] }); - const [history, setHistory] = useState(new Array(150).fill([])); + const [history, setHistory] = useState(new Array(Number(import.meta.env.CLIENT_GRAPH_STEPS)).fill([])); useEffect(() => { if (dynamicData) { diff --git a/src/client/components/chart-cards/network.tsx b/src/client/components/chart-cards/network.tsx index 6731194..2c18246 100644 --- a/src/client/components/chart-cards/network.tsx +++ b/src/client/components/chart-cards/network.tsx @@ -4,7 +4,7 @@ import { ChartCard } from './index'; export const Network = () => { const { data: dynamicData } = useQuery({ queryKey: ['dynamic'] }); - const [history, setHistory] = useState(new Array(150).fill([])); + const [history, setHistory] = useState(new Array(Number(import.meta.env.CLIENT_GRAPH_STEPS)).fill([])); useEffect(() => { if (dynamicData) { diff --git a/src/client/components/chart-cards/temps.tsx b/src/client/components/chart-cards/temps.tsx index d9de4cc..f75de3e 100644 --- a/src/client/components/chart-cards/temps.tsx +++ b/src/client/components/chart-cards/temps.tsx @@ -5,7 +5,7 @@ import { ChartCard } from './index'; export const Temps = () => { const { data: staticData } = useQuery({ queryKey: ['static'] }); const { data: dynamicData } = useQuery({ queryKey: ['dynamic'] }); - const [history, setHistory] = useState(new Array(150).fill([])); + const [history, setHistory] = useState(new Array(Number(import.meta.env.CLIENT_GRAPH_STEPS)).fill([])); useEffect(() => { if (dynamicData) { diff --git a/src/client/vite-env.d.ts b/src/client/vite-env.d.ts index 11f02fe..5b73224 100644 --- a/src/client/vite-env.d.ts +++ b/src/client/vite-env.d.ts @@ -1 +1,14 @@ /// + +interface ImportMetaEnv { + readonly CLIENT_GRAPH_STEPS: string; + readonly CLIENT_PORT: string; + readonly CLIENT_REFETCH_INTERVAL: string; + readonly SERVER_ACTIVE_WINDOW: string; + readonly SERVER_PORT: string; + readonly SERVER_REFRESH_INTERVAL: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/src/stats-server/main.rs b/src/stats-server/main.rs index eff073e..d8e356a 100644 --- a/src/stats-server/main.rs +++ b/src/stats-server/main.rs @@ -1,4 +1,5 @@ use axum::{extract::State, http::Response, response::IntoResponse, routing::get, Router, Server}; +use dotenv::dotenv; use serde_json::{json, Value}; use std::{ sync::{Arc, Mutex}, @@ -27,6 +28,18 @@ impl Default for AppState { #[tokio::main] async fn main() { + dotenv().ok(); + let refresh_interval = Duration::from_millis( + std::env::var("SERVER_REFRESH_INTERVAL") + .unwrap() + .parse::() + .unwrap(), + ); + let active_window = std::env::var("SERVER_ACTIVE_WINDOW") + .unwrap() + .parse::() + .unwrap(); + let port = std::env::var("SERVER_PORT").unwrap(); let app_state = AppState::default(); let router = Router::new() @@ -45,7 +58,7 @@ async fn main() { let now = Instant::now(); let latest = app_state.latest.lock().unwrap().clone(); - if (now - latest).as_millis() < 10000 { + if (now - latest).as_millis() < active_window { sys.refresh_cpu(); sys.refresh_memory(); components.refresh(); @@ -82,11 +95,12 @@ async fn main() { } } - std::thread::sleep(Duration::from_millis(200)); + std::thread::sleep(refresh_interval); } }); - let server = Server::bind(&"0.0.0.0:3001".parse().unwrap()).serve(router.into_make_service()); + let server = Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap()) + .serve(router.into_make_service()); let addr = server.local_addr(); println!("Listening on {addr}"); diff --git a/vite.config.ts b/vite.config.ts index 235b204..9097ed4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,6 +4,7 @@ import { defineConfig } from 'vite'; // https://vitejs.dev/config/ export default defineConfig({ + envPrefix: ['CLIENT', 'SERVER'], plugins: [react()], resolve: { alias: {