docs: correct the false Arc<Mutex> MakeWriter claim
Both the spec and the plan asserted that Arc<Mutex<RotatingLogWriter>> satisfies tracing-subscriber's MakeWriter via impl MakeWriter for Arc<W>. That impl requires &'a W: io::Write, and &Mutex<W> does not implement io::Write. The error reached the implementer and cost a fix round before being caught; the shipped code uses a bare Mutex. Corrections are marked inline so the mistake stays visible rather than being silently erased. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EGntTHCW3sEPy1VBRopNNp
This commit is contained in:
@@ -168,9 +168,11 @@ The daemon currently logs only to stderr, which launchd discards. Give it `log_d
|
|||||||
|
|
||||||
**Interfaces:**
|
**Interfaces:**
|
||||||
- Consumes: `impl io::Write for RotatingLogWriter` from Task 1.
|
- Consumes: `impl io::Write for RotatingLogWriter` from Task 1.
|
||||||
- Produces: `pub(crate) fn daemon_writer(log_dir: &Path) -> std::io::Result<Arc<Mutex<RotatingLogWriter>>>`. No later task depends on this.
|
- Produces: `pub(crate) fn daemon_writer(log_dir: &Path) -> std::io::Result<Mutex<RotatingLogWriter>>`. No later task depends on this.
|
||||||
|
|
||||||
`tracing-subscriber` 0.3 already implements `MakeWriter` for `Mutex<W> where W: io::Write` and for `Arc<W>`, so `Arc<Mutex<RotatingLogWriter>>` satisfies `with_writer` directly. No adapter type is needed.
|
`tracing-subscriber` 0.3 implements `MakeWriter` for `Mutex<W> where W: io::Write` (`fmt/writer.rs:808`), so a plain `Mutex<RotatingLogWriter>` satisfies `with_writer` directly. No adapter type is needed.
|
||||||
|
|
||||||
|
**Corrected 2026-08-01.** This step originally specified `Arc<Mutex<RotatingLogWriter>>`, on the false premise that `impl MakeWriter for Arc<W>` would cover it. That impl requires `&'a W: io::Write`, and `&Mutex<W>` does not implement `io::Write`. The error was caught during implementation and cost one fix round; the shipped code uses a bare `Mutex`.
|
||||||
|
|
||||||
- [ ] **Step 1: Write the failing test**
|
- [ ] **Step 1: Write the failing test**
|
||||||
|
|
||||||
@@ -215,16 +217,16 @@ Prepend to `crates/xy/src/logging.rs`, above the test module:
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Mutex;
|
||||||
use xy_supervisor::logs::RotatingLogWriter;
|
use xy_supervisor::logs::RotatingLogWriter;
|
||||||
|
|
||||||
const LOG_FILE_MAX_BYTES: u64 = 10 * 1024 * 1024;
|
const LOG_FILE_MAX_BYTES: u64 = 10 * 1024 * 1024;
|
||||||
const LOG_FILE_KEEP: usize = 5;
|
const LOG_FILE_KEEP: usize = 5;
|
||||||
|
|
||||||
pub(crate) fn daemon_writer(log_dir: &Path) -> std::io::Result<Arc<Mutex<RotatingLogWriter>>> {
|
pub(crate) fn daemon_writer(log_dir: &Path) -> std::io::Result<Mutex<RotatingLogWriter>> {
|
||||||
let writer = RotatingLogWriter::open(&log_dir.join("xy.log"), LOG_FILE_MAX_BYTES, LOG_FILE_KEEP)?;
|
let writer = RotatingLogWriter::open(&log_dir.join("xy.log"), LOG_FILE_MAX_BYTES, LOG_FILE_KEEP)?;
|
||||||
|
|
||||||
Ok(Arc::new(Mutex::new(writer)))
|
Ok(Mutex::new(writer))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -154,11 +154,17 @@ which is too late to open a log file for the logger itself.
|
|||||||
For the `Cmd::Daemon` arm only, the subscriber writes to `stderr.and(file)` via
|
For the `Cmd::Daemon` arm only, the subscriber writes to `stderr.and(file)` via
|
||||||
`MakeWriterExt`, where the file half is `log_dir/xy.log` backed by the existing
|
`MakeWriterExt`, where the file half is `log_dir/xy.log` backed by the existing
|
||||||
`xy_supervisor::logs::RotatingLogWriter` (10 MB × 5, the same rotation used for
|
`xy_supervisor::logs::RotatingLogWriter` (10 MB × 5, the same rotation used for
|
||||||
per-server logs). No adapter type is needed: `tracing-subscriber` 0.3 already
|
per-server logs). No adapter type is needed: `tracing-subscriber` 0.3
|
||||||
implements `MakeWriter` for `Mutex<W> where W: io::Write` (`fmt/writer.rs:808`)
|
implements `MakeWriter` for `Mutex<W> where W: io::Write`
|
||||||
and for `Arc<W> where W: MakeWriter` (`fmt/writer.rs:694`), so
|
(`fmt/writer.rs:808`), so a plain `Mutex<RotatingLogWriter>` satisfies
|
||||||
`Arc<Mutex<RotatingLogWriter>>` satisfies the bound once Task 1 lands the
|
`with_writer` once the `io::Write` impl lands.
|
||||||
`io::Write` impl.
|
|
||||||
|
**Corrected 2026-08-01.** An earlier draft of this section claimed
|
||||||
|
`Arc<Mutex<RotatingLogWriter>>` also satisfied the bound, via
|
||||||
|
`impl MakeWriter for Arc<W>`. That is false: the `Arc` impl
|
||||||
|
(`fmt/writer.rs:694`) requires `&'a W: io::Write`, and `&Mutex<W>` does not
|
||||||
|
implement `io::Write`. The claim survived into the implementation plan and cost
|
||||||
|
a fix round before being caught. The shipped code uses a bare `Mutex`.
|
||||||
|
|
||||||
Every other subcommand keeps stderr-only logging; CLI output does not belong in
|
Every other subcommand keeps stderr-only logging; CLI output does not belong in
|
||||||
the daemon's log.
|
the daemon's log.
|
||||||
|
|||||||
Reference in New Issue
Block a user