Skip to content

Address open review feedback from PR #8263 (TRX streaming store)#8285

Open
Evangelink wants to merge 3 commits into
mainfrom
dev/amauryleve/trx-followup
Open

Address open review feedback from PR #8263 (TRX streaming store)#8285
Evangelink wants to merge 3 commits into
mainfrom
dev/amauryleve/trx-followup

Conversation

@Evangelink
Copy link
Copy Markdown
Member

Follow-up to #8263 addressing the open review threads on the merged PR.

Changes

  • TrxTestResultExtractor doc comment — the serializer per-record cap is 64 MiB (TrxTestResultSerializer.MaxRecordLengthBytes), not 16 MiB as the comment stated. Updated so the rationale for MaxCapturedFieldChars cites the correct number. (Copilot review threads x2)
  • TrxResultStreamingStore.WriteRecordWithRetryAsync nullable consistency — the two bare ExceptionDispatchInfo.Capture(lastError).Throw() rethrows now use the null-forgiving operator, matching the final Capture(lastError!).Throw() at the end of the method. (Copilot review thread)
  • TRX streaming-store writer no longer blocks a threadpool thread — switched from ITask.Run to ITask.RunLongRunning so the BlockingCollection<T>.TryTake poll loop (which blocks for up to _flushIntervalMs while idle) runs on its own dedicated background thread instead of starving the threadpool. (@Youssef1313 review thread)

cc @Youssef1313

- Fix doc comment in TrxTestResultExtractor: the serializer per-record cap
  is 64 MiB, not 16 MiB.
- Apply the null-forgiving operator consistently on the bare `lastError`
  rethrows in `TrxResultStreamingStore.WriteRecordWithRetryAsync` so the
  nullable-flow analysis stays satisfied across all rethrow paths.
- Switch the TRX streaming-store writer task from `Task.Run` to
  `ITask.RunLongRunning` so the `BlockingCollection<T>.TryTake` poll
  loop no longer blocks a shared threadpool thread.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 16, 2026 11:17
// BlockingCollection<T>.TryTake blocks the calling thread for up to _flushIntervalMs when
// the queue is idle. Running the writer on a dedicated long-running thread instead of the
// shared threadpool keeps it from starving threadpool consumers while it sleeps on the queue.
_writerTask = task.RunLongRunning(WriteLoopAsync, "TRX streaming store writer", CancellationToken.None);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The awaits in WriteLoopAsync might get you back on threadpool so I don't think this is a good fix.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Follow-up to PR #8263 that tightens documentation/nullable consistency in the TRX streaming store, and attempts to move the streaming-writer loop off the shared threadpool to reduce contention during idle waits.

Changes:

  • Corrected TrxTestResultExtractor comment to reflect the serializer’s 64 MiB per-record cap.
  • Made ExceptionDispatchInfo.Capture(lastError) rethrows nullable-consistent via lastError!.
  • Switched the streaming-store writer startup from ITask.Run to ITask.RunLongRunning.
Show a summary per file
File Description
src/Platform/Microsoft.Testing.Extensions.TrxReport/Streaming/TrxTestResultExtractor.cs Updates rationale comment to reference the correct serializer record-size cap (64 MiB).
src/Platform/Microsoft.Testing.Extensions.TrxReport/Streaming/TrxResultStreamingStore.cs Starts the writer via RunLongRunning and aligns nullable usage in retry rethrow paths.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment on lines +69 to +72
// BlockingCollection<T>.TryTake blocks the calling thread for up to _flushIntervalMs when
// the queue is idle. Running the writer on a dedicated long-running thread instead of the
// shared threadpool keeps it from starving threadpool consumers while it sleeps on the queue.
_writerTask = task.RunLongRunning(WriteLoopAsync, "TRX streaming store writer", CancellationToken.None);
Copy link
Copy Markdown
Member Author

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 21/21 dimensions clean — no findings.

All three changes are correct:

  • RunLongRunning: The API exists on ITask/SystemTask and correctly spawns a dedicated background thread, keeping the blocking BlockingCollection.TryTake off the shared threadpool. Rationale in the comment is accurate.
  • lastError!: Both null-forgiving operators are safe. The catch sites are only reachable after at least one loop iteration that unconditionally assigns lastError; null is impossible there.
  • Comment 16 MiB64 MiB: Matches the actual MaxRecordLengthBytes = 64 * 1024 * 1024 constant in TrxTestResultSerializer.cs; the MaxCapturedFieldChars = 1 MiB truncation cap is still well below 64 MiB.

Generated by Expert Code Review (on open) for issue #8285 · ● 8.6M

@Evangelink
Copy link
Copy Markdown
Member Author

@copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 16, 2026

@copilot address review comments

Addressed in 6fbd731. The TRX streaming writer loop is now await-free/synchronous while running on the long-running background thread, so the BlockingCollection.TryTake polling and retry/flush/log waits stay off the shared threadpool. Targeted build and TRX report tests pass.

Copilot AI review requested due to automatic review settings May 16, 2026 14:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment on lines +223 to +225
_logger.LogErrorAsync(
$"TRX streaming store writer faulted; intermediate file may be incomplete. {discarded} record(s) were dropped from the in-memory queue and will not appear in the TRX.",
ex).ConfigureAwait(false);
ex).GetAwaiter().GetResult();

await _logger.LogErrorAsync(
_logger.LogErrorAsync(
$"Failed to write TRX record {i + 1}/{batch.Count} after {MaxWriteRetries} retries; truncating to last good record. {unwritten} record(s) from this batch will not appear in the TRX.",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants