Write a complete, single-file Rust service using tokio that manages a set of background "watchers" connected by channels, with safe shared state and robust error handling. This mirrors a real async Rust service (à la ninesentry / aystreamer). ### What it does A `WatcherManager` owns N async "watcher" tasks. Each watcher periodically polls a mock source (`async fn mock_fetch(id: u32) -> Result, FetchError>` — returns Ok with 0–3 random items, or Err ~15% of the time). Items a watcher produces are forwarded through a channel to a single consumer task that aggregates them. The manager supports adding/removing watchers at runtime and a clean shutdown. ### Requirements (idiomatic async Rust) 1. **Channels:** use `tokio::sync::mpsc` (or `broadcast`) to send items from watchers to the consumer. Demonstrate correct sender/receiver ownership and dropping (no deadlock on shutdown). 2. **Shared state:** the manager's live watcher set must be shared safely across tasks — use `Arc>` or `Arc>`. Add/remove must be race-free. 3. **Error handling:** define a `thiserror`-style (or manual `enum`) error type. Polling failures must be logged/handled per-watcher and must NOT abort the whole manager; a watcher that fails repeatedly (>5 consecutive) should be marked unhealthy. 4. **Cancellation / shutdown:** on a `shutdown()` signal (use a `tokio::sync::oneshot` or `CancellationToken`), every watcher and the consumer must terminate cleanly within their current poll cycle — no leaked tasks, no panics, no hung select!. 5. **Backpressure:** if the consumer is slow, the channel must not grow unbounded (bounded channel); document the chosen bound and what happens when full. 6. **Idiomatic types:** use traits + enums where natural, `Result` everywhere errors can occur, `#[derive(Debug, Clone)]` on shared data, and `serde::Serialize` on the aggregated output struct. ### Included test Include a `#[tokio::test]` (or a `main` that asserts) that: - a) Spawns a manager with 4 watchers, lets it run ~500ms, shuts down, and asserts all tasks joined (no hang) and the consumer received >0 items. - b) Asserts that injecting a watcher whose `mock_fetch` always errors gets marked unhealthy after 5 consecutive failures (without crashing others). - c) Asserts add + remove of a watcher at runtime updates the live count with no race (no panic on concurrent mutation). Provide clean, well-commented code. Must compile and run with current stable Rust + tokio (single file, deps via comments or assume `tokio = { features = ["full"] }`, `serde`, `thiserror`).