diff options
Diffstat (limited to 'src/api/dashboard/mod.rs')
| -rw-r--r-- | src/api/dashboard/mod.rs | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/api/dashboard/mod.rs b/src/api/dashboard/mod.rs index 7679787..dd454ec 100644 --- a/src/api/dashboard/mod.rs +++ b/src/api/dashboard/mod.rs @@ -21,10 +21,10 @@ use std::time::Duration; use axum::http::{HeaderValue, StatusCode, header::CONTENT_TYPE}; use axum::response::sse::{Event, KeepAlive, Sse}; use axum::response::{Html, IntoResponse, Response}; -use axum::routing::get; +use axum::routing::{get, post}; use axum::{Extension, Router}; use serde_json::{Map, Value as JsonValue, json}; -use tokio::sync::{broadcast, watch}; +use tokio::sync::{Notify, broadcast, watch}; use tokio::time::Instant; use crate::locks::MutexExt; @@ -60,6 +60,8 @@ struct Hub { /// `{"paths": [...]}`, or `{"all": true}` if too many or not known. documents: broadcast::Sender<Arc<String>>, control: Mutex<Control>, + /// Someone asked for it now (`refresh`): a tick at once, members asked again. + poke: Notify, /// True once the node stops: every client gets an `offline` event, and its stream /// ends (so the HTTP server needn't wait for clients to go). closing: watch::Receiver<bool>, @@ -81,6 +83,7 @@ impl Hub { latest, patches, documents, + poke: Notify::new(), control: Mutex::new(Control { running: false, wanted_until: Instant::now(), @@ -151,7 +154,13 @@ impl Hub { }))); last = Some(snapshot); } - tokio::time::sleep(TICK).await; + let poked = tokio::select! { + () = tokio::time::sleep(TICK) => false, + () = self.poke.notified() => true, + }; + if poked { + graph_due = Instant::now(); + } if let Some(changed) = document_changes(&mut changes) { let _ = self.documents.send(Arc::new(changed.to_string())); } @@ -360,6 +369,7 @@ pub(crate) fn router(state: AppState, closing: watch::Receiver<bool>) -> Router< .route("/admin/dashboard", get(page_html)) .route("/admin/dashboard/state", get(current_state)) .route("/admin/dashboard/events", get(events)) + .route("/admin/dashboard/refresh", post(refresh)) .layer(Extension(Hub::new(state, closing))) } @@ -389,6 +399,14 @@ async fn page_html() -> Html<&'static str> { Html(page().1.as_str()) } +/// `POST /admin/dashboard/refresh`: a tick now rather than at the next `TICK`, and the +/// members asked for their links again; what changed comes as events, as ever. +async fn refresh(Extension(hub): Extension<Arc<Hub>>) -> StatusCode { + hub.want(); + hub.poke.notify_one(); + StatusCode::NO_CONTENT +} + /// `GET /admin/dashboard/state`: the latest snapshot, for a client that wants it whole. async fn current_state(Extension(hub): Extension<Arc<Hub>>) -> Response { hub.want(); |
