Files
todo-baggins/src/server/updates.rs
Matouš Volf f3508de4eb
Some checks failed
conventional pull request title check / conventional pull request title check (pull_request) Successful in 4s
conventional commit messages check / conventional commit messages check (pull_request) Successful in 11s
dotenv-linter check / dotenv-linter check (pull_request) Successful in 9s
GitLeaks check / GitLeaks check (pull_request) Successful in 11s
markdownlint check / markdownlint check (pull_request) Successful in 20s
htmlhint check / htmlhint check (pull_request) Successful in 25s
hadolint check / hadolint check (pull_request) Failing after 57s
checkov check / checkov check (pull_request) Successful in 1m20s
Prettier check / Prettier check (pull_request) Successful in 34s
ShellCheck check / ShellCheck check (pull_request) Successful in 29s
Stylelint check / Stylelint check (pull_request) Failing after 29s
yamllint check / yamllint check (pull_request) Successful in 24s
Rust check / Rust check (pull_request) Failing after 2m6s
actionlint check / actionlint check (pull_request) Successful in 7s
chore: upgrade to Dioxus 0.7
2025-12-17 19:47:28 +01:00

77 lines
2.2 KiB
Rust

use dioxus::{
fullstack::{WebSocketOptions, Websocket},
prelude::*,
};
use serde::{Deserialize, Serialize};
#[cfg(feature = "server")]
use rand::random;
#[cfg(feature = "server")]
use tokio::sync::Mutex;
#[derive(Serialize, Deserialize)]
pub(crate) struct UpdateEvent;
#[cfg(feature = "server")]
mod server_only {
use std::{
collections::{HashMap, HashSet},
ops::Deref,
sync::LazyLock,
};
use dioxus::fullstack::TypedWebsocket;
use tokio::sync::{Mutex, RwLock};
use crate::server::updates::UpdateEvent;
pub(super) struct SubscribedClient {
pub(super) websocket: Mutex<TypedWebsocket<UpdateEvent, UpdateEvent>>,
}
pub(super) struct SubscribedClients(RwLock<HashMap<u64, SubscribedClient>>);
impl Deref for SubscribedClients {
type Target = RwLock<HashMap<u64, SubscribedClient>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub(super) static SUBSCRIBED_CLIENTS: LazyLock<SubscribedClients> =
LazyLock::new(|| SubscribedClients(RwLock::new(HashMap::new())));
pub(crate) async fn publish_update() {
let mut disconnected_client_ids = HashSet::new();
let subscribed_clients = SUBSCRIBED_CLIENTS.read().await;
for (id, client) in subscribed_clients.iter() {
if let Err(_) = client.websocket.lock().await.send(UpdateEvent).await {
disconnected_client_ids.insert(id.clone());
}
}
drop(subscribed_clients);
if !disconnected_client_ids.is_empty() {
let mut subscribed_clients = SUBSCRIBED_CLIENTS.write().await;
subscribed_clients.retain(|id, _| !disconnected_client_ids.contains(id));
}
}
}
#[cfg(feature = "server")]
pub(super) use server_only::*;
#[get("/api/subscribe_to_updates")]
pub(crate) async fn subscribe_to_updates(
websocket_options: WebSocketOptions,
) -> Result<Websocket<UpdateEvent, UpdateEvent>> {
Ok(websocket_options.on_upgrade(move |socket| async move {
SUBSCRIBED_CLIENTS.write().await.insert(
random(),
SubscribedClient {
websocket: Mutex::new(socket),
},
);
}))
}