Skip to content

[chore] Report completed storage requests from the latency histogram - #192

Merged
0oshowero0 merged 1 commit into
Ascend:mainfrom
0oshowero0:fix/storage-request-ops-completion
Oct 13, 2026
Merged

0oshowero0 merged 1 commit into
Ascend:mainfrom
0oshowero0:fix/storage-request-ops-completion

Conversation

@0oshowero0

@0oshowero0 0oshowero0 commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

op_stats.request_count is documented as the number of completed requests:

  • the controller collects it as tq_storage_request_ops;
  • the timeout diagnosis prints it as completed=;
  • the Grafana panel compares it against arrivals as "completed".

It is actually read from request_total, which TQMetricsExporter.measure() increments on entry, before the handler runs. The two numbers agree today only because a storage unit has a single worker, and that worker answers GET_METRICS after every earlier handler has returned.

docs/metrics.md also draws a conclusion that these counters cannot support: it says that a sustained gap between arrivals and tq_storage_request_ops means requests are arriving and not finishing. Because the same worker answers the collector, the counters are only reported between requests. A unit stuck in a handler stops answering instead; the collector skips it, and its gauges stay at their last values.

Found while reviewing #189.

Change

  • request_count: read it from the request-duration histogram. measure() observes the histogram when the handler returns or raises, and latency_avg in the same function already uses its count. The field then means "completed" by construction. No reported value changes today.
  • docs/metrics.md: say what the collected counters can and cannot show, and point to the storage unit's own endpoint instead. That endpoint is served by its own thread, so tq_storage_request_total minus tq_storage_request_duration_seconds_count gives the handlers still running, even while the worker is stuck. Also, tq_storage_request_total is now described as requests whose handler has started; it was "Total requests processed".

Validation

This PR adds no test. No reported value changes, and telling the old source from the new one would require reading the metrics while a handler is still running, which the single worker never does.

Checks run:

  • pre-commit (ruff, ruff-format, mypy)
  • python -m compileall -q transfer_queue tutorial tests
  • python -m pytest -q, excluding tests/e2e and the Yuanrong e2e tests, which need the optional datasystem package: 671 passed, 8 skipped on the first revision. One run of tests/test_controller.py::test_controller_clear_meta failed when the local Raylet crashed; the file passes on rerun. Later revisions changed only comments and docs, and tests/test_storage_request_retry.py and tests/test_metrics.py pass.

Copilot AI balanced review requested due to automatic review settings October 13, 2026 14:31
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-13T14:34:41.417943Z 7285258 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused metric correction is consistent with existing histogram semantics and has appropriate regression coverage.

0 open findings

What changed in this PR

Corrects storage operation completion metrics to exclude in-flight handlers.

Changes:

  • Derives completed request counts from histogram observations.
  • Adds coverage for running and failed handlers.
File Description
transfer_queue/​storage/​simple_storage.py Reports completed operations accurately.
tests/​test_storage_request_retry.py Tests in-flight and failed handler counts.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7285258c34

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"request_count": counter._value.get(),
# Observed when the handler returns or raises; request_total counts entry,
# which would hide a handler that never finishes.
"request_count": duration_count,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Serve in-flight metrics outside the serialized worker

When a real storage handler stalls, this completion value cannot be queried concurrently: _worker_routine synchronously runs the single _process_one_worker_request path (transfer_queue/storage/simple_storage.py:1048-1067), and GET_METRICS is another branch of that same dispatcher at lines 1118-1119. The collector's metrics request therefore waits behind the stuck request (and times out), while after the handler returns the histogram has already been observed, so tq_storage_request_ops never exposes the intended arrival/completion gap. The new test only passes because it calls _handle_get_metrics() directly from a second thread, which the supported ZMQ path cannot do; this snapshot needs an independently serviced path and a test through the real dispatcher.

AGENTS.md reference: AGENTS.md:L17-L18

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed. A storage unit has one worker, and it answers GET_METRICS only after the previous handler has returned. Through the supported path, request_total and the histogram count are therefore always equal when read. A stuck handler shows up as an unanswered collector query or probe (unit_not_serving), not as a gap.

I've narrowed the PR to match (4146d6d):

  • Framing: the change now only makes request_count mean "completed" by construction, from the same histogram that latency_avg uses, and it states that no reported value changes.
  • Docs: docs/metrics.md claimed that the collected gap reveals unfinished requests. That claim is now removed.
  • Test: it stays as a contract test for the field, and its docstring now says that this interleaving is not reachable through the worker today.

I don't think a separate metrics path is needed. The storage unit's own endpoint is served by its own thread, so handlers still in progress are already visible there as tq_storage_request_total minus tq_storage_request_duration_seconds_count; the updated doc now points there.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Follow-up: I dropped the test in 4a223d5. It could only tell the old and new source apart by reading the metrics while a handler is still running, which is the interleaving this worker never produces, so it guarded nothing a user can observe. The PR is now the field source plus the docs/metrics.md correction.

@0oshowero0
0oshowero0 force-pushed the fix/storage-request-ops-completion branch from 7285258 to 4146d6d Compare October 13, 2026 14:45
@0oshowero0 0oshowero0 changed the title [fix] Count storage request completions after the handler finishes [chore] Report completed storage requests from the latency histogram Oct 13, 2026
op_stats.request_count is documented as completed requests, but it was
read from request_total, which measure() increments on entry. The two
agree only because a storage unit's single worker answers GET_METRICS
after every earlier handler has returned. Read the request-duration
histogram instead, which latency_avg already uses, so the field means
completed by construction. No reported value changes.

docs/metrics.md claimed that a gap between arrivals and
tq_storage_request_ops shows requests that arrived and did not finish.
The same worker answers the collector, so it cannot: a stuck unit stops
answering instead. Say so, and point to the storage unit's own endpoint,
which can show handlers still running.

Signed-off-by: 0oshowero0 <o0shower0o@outlook.com>
@0oshowero0
0oshowero0 force-pushed the fix/storage-request-ops-completion branch from 4146d6d to 4a223d5 Compare October 13, 2026 14:48
@0oshowero0
0oshowero0 merged commit 1195ec1 into Ascend:main Oct 13, 2026
8 checks passed
@0oshowero0
0oshowero0 deleted the fix/storage-request-ops-completion branch October 13, 2026 15:01
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.

2 participants