1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// ABOUTME: Process-wide signal that a chromiumoxide browser is being torn down
// ABOUTME: Lets a tracing layer suppress the expected post-close WS-reset error from chromiumoxide
//
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2026 dravr.ai
//! Browser-teardown signal published to the rest of the process.
//!
//! `chromiumoxide` drives Chrome over a DevTools-Protocol WebSocket. When the
//! browser closes, Chrome exits without sending the polite WS Close frame, so
//! chromiumoxide's handler task observes a `Ws(Protocol(
//! ResetWithoutClosingHandshake))` and emits an `error!` log. Nothing is
//! actually broken — the work completed before the close. To avoid this
//! lifecycle noise reaching alerting, advertise a short *"teardown in
//! progress"* window via this module; a tracing `Filter` layer can suppress
//! `chromiumoxide::handler` ERROR events **only** while the window is open.
//!
//! - Each [`TeardownGuard::new`] increments the depth counter.
//! - Dropping the guard schedules a task that, after a grace window,
//! decrements it — covering the gap between `browser.close().await`
//! returning and the handler task observing the WS reset.
//!
//! The counter is `AtomicU32`, so concurrent teardowns compose.
use ;
use Duration;
use sleep;
/// Grace window held open after a guard is dropped so the chromiumoxide
/// handler task can emit its post-close WS-reset error inside the
/// suppression window.
const TEARDOWN_GRACE: Duration = from_millis;
/// Process-wide counter of in-flight browser teardowns. Public **for reading
/// only** via [`is_in_progress`]; treat as opaque from outside.
static TEARDOWN_DEPTH: AtomicU32 = new;
/// Returns `true` while one or more chromiumoxide browsers are inside their
/// teardown grace window.
/// RAII guard that opens a teardown grace window for the duration of a
/// browser-close call.
///
/// Construct **before** calling `browser.close().await`; let it drop at the
/// end of the close path. Must be created from inside a tokio runtime; the
/// grace-window release uses [`tokio::spawn`].