Hot-reload content on a NATS trigger instead of requiring a restart
Deploy / deploy (push) Successful in 29s
Deploy / deploy (push) Successful in 29s
questions is now Arc<ArcSwap<HashMap<...>>> - readers do a lock-free atomic load (state.questions.load().get(&id).cloned()), never blocking on or blocked by a reload. content::watch_for_reload subscribes to portal.content.reload (published by the questions repo's own CI after it lints a push - see that repo's lint-and-reload.yml) and swaps in a freshly re-fetched HashMap on each message. A fetch/parse failure logs and keeps serving the last-good content rather than clearing it.
This commit is contained in:
+10
-1
@@ -30,6 +30,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let content_branch = std::env::var("CONTENT_BRANCH").unwrap_or_else(|_| "main".to_string());
|
||||
let questions = content::load_questions_from_gitea(&content_repo, &content_branch, "questions").await?;
|
||||
tracing::info!(count = questions.len(), repo = %content_repo, branch = %content_branch, "loaded content");
|
||||
let questions = Arc::new(arc_swap::ArcSwap::from_pointee(questions));
|
||||
|
||||
let nats_url =
|
||||
std::env::var("NATS_URL").unwrap_or_else(|_| "nats://127.0.0.1:4222".to_string());
|
||||
@@ -56,11 +57,19 @@ async fn main() -> anyhow::Result<()> {
|
||||
tracing::warn!("GARAGE_* env vars not set - file upload fields will fail closed");
|
||||
}
|
||||
|
||||
tokio::spawn(content::watch_for_reload(
|
||||
nats.clone(),
|
||||
content_repo,
|
||||
content_branch,
|
||||
"questions".to_string(),
|
||||
questions.clone(),
|
||||
));
|
||||
|
||||
let state = AppState {
|
||||
leptos_options: leptos_options.clone(),
|
||||
nats,
|
||||
jetstream,
|
||||
questions: std::sync::Arc::new(questions),
|
||||
questions,
|
||||
oidc: oidc_state,
|
||||
garage,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user