fix(admin): clear session-expired flag on successful browser restart (0.53.1)
A successful `coordinated_restart` re-runs `on_launch`, which re-injects PHPSESSID and re-probes via `verify_session_with_recircuit` — so reaching `Ok(())` proves the session is live. But the handler never dropped the sticky `session_expired` flag, so the admin UI continued to report "Session Expired" and chapter workers kept idling until the operator made a second click on "Clear expired" (or pushed a new cookie). The fix is one line in `restart_browser`: on `Ok(())`, call `c.session.clear_expired()`. The error path still leaves the flag set since a failed restart means the probe didn't confirm. Adds a focused `clear_expired_flips_sticky_flag_without_touching_session` unit test to pin the controller-side semantic; the existing `update_persists_and_clears_expired_then_round_trips` test continues to cover the cookie-refresh path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
@@ -1470,7 +1470,7 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mangalord"
|
name = "mangalord"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argon2",
|
"argon2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mangalord"
|
name = "mangalord"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
default-run = "mangalord"
|
default-run = "mangalord"
|
||||||
|
|
||||||
|
|||||||
@@ -233,6 +233,13 @@ async fn restart_browser(
|
|||||||
) -> AppResult<Json<RestartResponse>> {
|
) -> AppResult<Json<RestartResponse>> {
|
||||||
let c = require_crawler(&state)?;
|
let c = require_crawler(&state)?;
|
||||||
let result = c.browser_manager.coordinated_restart(c.drain_deadline).await;
|
let result = c.browser_manager.coordinated_restart(c.drain_deadline).await;
|
||||||
|
// A successful coordinated_restart re-runs on_launch, which re-injects
|
||||||
|
// PHPSESSID and re-probes — i.e. the session is live. Drop the sticky
|
||||||
|
// `session_expired` flag so chapter workers stop idling without
|
||||||
|
// requiring a second click on "Clear expired".
|
||||||
|
if result.is_ok() {
|
||||||
|
c.session.clear_expired();
|
||||||
|
}
|
||||||
// Push the post-restart browser phase to live subscribers immediately.
|
// Push the post-restart browser phase to live subscribers immediately.
|
||||||
c.status.poke();
|
c.status.poke();
|
||||||
repo::admin_audit::insert(
|
repo::admin_audit::insert(
|
||||||
|
|||||||
@@ -164,4 +164,17 @@ mod tests {
|
|||||||
Some("good-sid-123")
|
Some("good-sid-123")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[sqlx::test(migrations = "./migrations")]
|
||||||
|
async fn clear_expired_flips_sticky_flag_without_touching_session(pool: PgPool) {
|
||||||
|
// The flag starts `true` per `controller(pool)`'s test wiring.
|
||||||
|
let c = controller(pool);
|
||||||
|
assert!(c.is_expired(), "test fixture starts with the flag set");
|
||||||
|
c.clear_expired();
|
||||||
|
assert!(!c.is_expired(), "clear_expired flips the sticky flag to false");
|
||||||
|
assert!(
|
||||||
|
c.current().await.is_none(),
|
||||||
|
"clear_expired does not invent a session"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mangalord-frontend",
|
"name": "mangalord-frontend",
|
||||||
"version": "0.53.0",
|
"version": "0.53.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user