Severity: Info
File: src/Servy.Core/IO/RotatingStreamWriter.cs around line 474 (rotation retry)
Description:
File rotation uses a synchronous Thread.Sleep(50) / Thread.Sleep(100) / Thread.Sleep(150) incremental backoff while waiting for antivirus / indexer / another process to release the old log file. This runs on the same thread that is draining the child process's stdout/stderr pipes.
Two consequences:
- Output capture stall. While rotation retries (up to ~300 ms per rotation under a single AV lock, more under repeated locks), the pipe pump does not advance. If the monitored child produces output at a high rate, its stdout/stderr pipe buffers fill and the child blocks on write — observable as the service appearing to hang briefly at every rotation boundary.
- Worst-case compounding. If multiple writers (e.g. separate stdout + stderr rotation both triggered by the same size boundary) both hit a lock, the stalls serialize.
Suggested fix:
- Move rotation off the write path entirely: enqueue a rotation request on a dedicated background Task and let Write() continue against the current file until the new one is ready; swap atomically.
- Or at minimum replace Thread.Sleep with an async retry and ensure the logging pipeline is awaiting.
- Or reduce the retry budget to a single quick attempt (<=25 ms total) and fall back to appending to the current file for one more cycle, since correctness (log captured) outweighs rotation punctuality.
This is lower-severity than the Thread.Sleep issue in DapperExecutor.cs because it doesn't park a pool thread — but the visible symptom (child process pause) is more user-facing.
Severity: Info
File:
src/Servy.Core/IO/RotatingStreamWriter.csaround line 474 (rotation retry)Description:
File rotation uses a synchronous
Thread.Sleep(50)/Thread.Sleep(100)/Thread.Sleep(150)incremental backoff while waiting for antivirus / indexer / another process to release the old log file. This runs on the same thread that is draining the child process's stdout/stderr pipes.Two consequences:
Suggested fix:
This is lower-severity than the Thread.Sleep issue in DapperExecutor.cs because it doesn't park a pool thread — but the visible symptom (child process pause) is more user-facing.