Skip to content

feat(analyzer): entity list endpoint - #258

Merged
rapids-bot[bot] merged 7 commits into
rapidsai:mainfrom
johanpel:pr-entity-list
Jul 13, 2026
Merged

feat(analyzer): entity list endpoint#258
rapids-bot[bot] merged 7 commits into
rapidsai:mainfrom
johanpel:pr-entity-list

Conversation

@johanpel

@johanpel johanpel commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Description

Adds POST /api/engines/{engine_id}/entities: a paginated query listing a
query's FSM entities ranked by longest resource-usage span (tiebroken by UUID),
to back the UI's long-entities view. Additive — no timeline changes.

Request: optional scope (resource / group), query-relative window, filters
(entity_type_name, min_usage_s), sort, page, and a per-query OperatorFilter.
Contract lives in quent-ui; a generic entities::list_entities ranks any
FsmCollection FSM, with operator filtering applied by the analyzer (kept out of
the generic filter).

Functional test over the fixed scenario captures events in memory via
CallbackExporter and reconstructs them with a new
quent-simulator-instrumentation::test_utils helper.

Depends on #256 and #257 (merged).

🤖 Generated with Claude Code

Related Issues

Part of #214, isolated from #240

@johanpel johanpel changed the title feat(query-engine): entity-list endpoint feat(analyzer): entity list endpoint Jun 25, 2026
@johanpel johanpel added non-breaking Introduces a non-breaking change feature request New feature or request labels Jun 25, 2026
@johanpel johanpel self-assigned this Jun 25, 2026
Comment thread examples/simulator/server/build.rs Outdated
<BulkTimelineRequest<QueryFilter, OperatorFilter> as TS>::export_all(&cfg)?;
<BulkTimelinesResponse as TS>::export_all(&cfg)?;

<EntityListRequest<QueryFilter> as TS>::export_all(&cfg)?;

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.

I think we need to be able to filter by operator here. Not sure if the exact right location, but the FE will want to filter long entities by operator presumably.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Add a dedicated, paginated entity-list query: POST /api/engines/{id}/entities.
The contract (entities module: scope, window, filter, sort, page, plus per-query
application params) and a generic FiniteStateMachine::try_from_fsm live in
quent-ui; UiAnalyzer::list_entities and its analyzer helper rank any application
FSM by its longest usage span on an optional scope, tiebroken by entity UUID.
Application-specific filters ride in the per-query params: the simulator filters
by operator via OperatorFilter, mirroring the timeline. Additive only — no
timeline changes.

The functional test captures the fixed scenario in memory via a CallbackExporter
(rapidsai#257) and reconstructs the event stream with a new
quent-simulator-instrumentation::test_utils helper. ts-rs bindings included.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
johanpel and others added 3 commits June 29, 2026 09:33
…elper

Move scope resolution to EntityScope::resolve in quent-ui (it is generic over
Model, not query-engine specific) and drop the free resolve_scope. Group the
generic list_entities helper's per-query inputs into a ListQuery struct so it
takes three arguments, and trim its docstrings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@johanpel
johanpel marked this pull request as ready for review June 29, 2026 09:21
# Conflicts:
#	domains/query_engine/tests/fixed/Cargo.toml
#	examples/simulator/analyzer/src/lib.rs

@dhruv9vats dhruv9vats left a comment

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.

Thanks @johanpel

} => {
let tree = ResourceTreeNode::try_new(model, *resource_group_id)?;
Ok(tree
.iter_leaf_ids()

@dhruv9vats dhruv9vats Jul 13, 2026

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.

does this mean that only leaf resources should have valid usages ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, this limitation is removed as a part of #191.

The resource concept will be unrelated to hierarchical trees of entities, also see:

https://github.com/rapidsai/quent/blob/main/crates/ref-tree/src/lib.rs
https://github.com/rapidsai/quent/blob/main/crates/resource/src/lib.rs

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 4c46418b-7275-452e-8ead-997dd745a720

📥 Commits

Reviewing files that changed from the base of the PR and between e170657 and fdbc1c3.

📒 Files selected for processing (2)
  • domains/query_engine/analyzer/src/entities.rs
  • examples/simulator/analyzer/src/lib.rs

📝 Walkthrough

Walkthrough

Adds a public entity-list query API with filtering, scope resolution, usage sorting, pagination, analyzer execution, an HTTP endpoint, simulator support, TypeScript exports, and fixed-scenario functional tests.

Changes

Entity list query

Layer / File(s) Summary
Entity list contracts and UI conversion
crates/ui/src/entities/*, crates/ui/src/paginate.rs, crates/ui/src/lib.rs
Defines serializable request, filter, scope, sorting, pagination, and response types, plus conversion from FSM usage data into UI entities.
Entity query execution
domains/query_engine/analyzer/src/entities.rs, domains/query_engine/analyzer/src/lib.rs
Filters FSMs, computes usage metrics within time windows and scopes, sorts with deterministic ID tie-breaking, paginates results, and builds responses.
Analyzer contract and HTTP endpoint
domains/query_engine/analyzer/src/ui.rs, domains/query_engine/server/src/ui.rs, domains/query_engine/server/src/timeline_cache.rs
Adds UiAnalyzer::list_entities, implements the HTTP POST route and OpenAPI metadata, and updates the test analyzer implementation.
Simulator implementation and TypeScript exports
examples/simulator/analyzer/src/lib.rs, examples/simulator/instrumentation/*, examples/simulator/server/build.rs
Resolves simulator requests, applies operator filtering, delegates entity queries, reconstructs recorded events for tests, and exports TypeScript bindings.
Fixed-scenario functional coverage
domains/query_engine/tests/fixed/Cargo.toml, domains/query_engine/tests/fixed/tests/list_entities.rs
Adds callback-enabled test dependencies and validates scope, ranking, minimum usage, pagination, total counts, and operator filtering.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding an entity list endpoint in the analyzer.
Description check ✅ Passed The description covers the change and related issues, and is detailed enough despite missing Testing and Screenshots sections.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (2)
domains/query_engine/server/src/ui.rs-265-276 (1)

265-276: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Publish the concrete entity-list schemas. request_body = Object and body = Object hide the actual contract for this endpoint; generated clients can’t discover entry, app_params, paging, or total. Register the concrete request/response types instead, along with any nested ToSchema types they depend on.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@domains/query_engine/server/src/ui.rs` around lines 265 - 276, Update the
Swagger metadata for the entity-list endpoint around its utoipa path definition
to reference the concrete request and response types instead of generic Object
schemas. Ensure the request type exposes entry, app_params, and paging fields,
the response type exposes the paged entities and total, and register all nested
types required by those schemas with ToSchema.
domains/query_engine/analyzer/src/entities.rs-101-106 (1)

101-106: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Prevent 32-bit pagination-offset overflow. PageParams uses u32, so (p.page as usize) * (p.max as usize) can overflow on 32-bit targets and panic or wrap; use saturating_mul so out-of-range pages return an empty slice.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@domains/query_engine/analyzer/src/entities.rs` around lines 101 - 106, Update
the pagination iterator construction in the page match to calculate the skip
offset with saturating multiplication, using the u32 page and max values before
or during conversion as appropriate. Ensure out-of-range pagination produces an
empty result without 32-bit overflow, while preserving the existing take
behavior.
🧹 Nitpick comments (1)
crates/ui/src/lib.rs (1)

257-261: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Describe the conversion contract rather than the grouping implementation.

This docstring explains the internal state-name grouping strategy. As per path instructions, “Docstrings state the contract, not the mechanism; do not restate types.”

Proposed documentation change
-/// Build from any application FSM via the [`FsmUsages`](a::fsm::FsmUsages)
-/// interface.
-///
-/// Usages are grouped onto their state's transition by state name, which is
-/// unique within an FSM.
+/// Converts an application FSM into its UI representation relative to `epoch`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ui/src/lib.rs` around lines 257 - 261, Update the documentation for
the conversion API near FsmUsages to describe its public conversion contract: it
builds from any application FSM implementing FsmUsages and preserves the
associated state-transition usages. Remove the explanation of grouping by state
name and avoid restating implementation details or type mechanics.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/simulator/analyzer/src/lib.rs`:
- Around line 262-290: The list_entities method must restrict task candidates to
request.query_id, not only the optional operator_id. Update the predicate passed
to entities::list_entities to require the task’s query/view identity to match
the requested query while preserving the operator filter, and add a regression
case covering overlapping queries in one model.

---

Other comments:
In `@domains/query_engine/analyzer/src/entities.rs`:
- Around line 101-106: Update the pagination iterator construction in the page
match to calculate the skip offset with saturating multiplication, using the u32
page and max values before or during conversion as appropriate. Ensure
out-of-range pagination produces an empty result without 32-bit overflow, while
preserving the existing take behavior.

In `@domains/query_engine/server/src/ui.rs`:
- Around line 265-276: Update the Swagger metadata for the entity-list endpoint
around its utoipa path definition to reference the concrete request and response
types instead of generic Object schemas. Ensure the request type exposes entry,
app_params, and paging fields, the response type exposes the paged entities and
total, and register all nested types required by those schemas with ToSchema.

---

Nitpick comments:
In `@crates/ui/src/lib.rs`:
- Around line 257-261: Update the documentation for the conversion API near
FsmUsages to describe its public conversion contract: it builds from any
application FSM implementing FsmUsages and preserves the associated
state-transition usages. Remove the explanation of grouping by state name and
avoid restating implementation details or type mechanics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 0ecb4efe-9538-4efd-bd6b-c71bec48d098

📥 Commits

Reviewing files that changed from the base of the PR and between 0bd67c7 and e170657.

⛔ Files ignored due to path filters (11)
  • Cargo.lock is excluded by !**/*.lock, !Cargo.lock
  • examples/simulator/server/ts-bindings/EntityListEntry.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/EntityListFilter.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/EntityListRequest.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/EntityListResponse.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/EntityScope.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/EntitySortKey.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/PageParams.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/Sort.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/SortDir.ts is excluded by !examples/simulator/server/ts-bindings/**
  • examples/simulator/server/ts-bindings/TimeWindow.ts is excluded by !examples/simulator/server/ts-bindings/**
📒 Files selected for processing (17)
  • crates/ui/src/entities/mod.rs
  • crates/ui/src/entities/request.rs
  • crates/ui/src/entities/response.rs
  • crates/ui/src/lib.rs
  • crates/ui/src/paginate.rs
  • domains/query_engine/analyzer/src/entities.rs
  • domains/query_engine/analyzer/src/lib.rs
  • domains/query_engine/analyzer/src/ui.rs
  • domains/query_engine/server/src/timeline_cache.rs
  • domains/query_engine/server/src/ui.rs
  • domains/query_engine/tests/fixed/Cargo.toml
  • domains/query_engine/tests/fixed/tests/list_entities.rs
  • examples/simulator/analyzer/src/lib.rs
  • examples/simulator/instrumentation/Cargo.toml
  • examples/simulator/instrumentation/src/lib.rs
  • examples/simulator/instrumentation/src/test_utils.rs
  • examples/simulator/server/build.rs

Comment thread examples/simulator/analyzer/src/lib.rs
- list_entities: restrict task candidates to the requested query, not
  only the optional operator filter. A task belongs to a query iff its
  operator is one of that query's operators; without this, tasks from a
  different query sharing a resource and overlapping the window leaked in.
- entities pagination: use saturating multiplication for the skip offset
  so an out-of-range page yields an empty page instead of overflowing
  usize on a 32-bit target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@johanpel

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 4d93e96 into rapidsai:main Jul 13, 2026
6 checks passed
felipeblazing added a commit to felipeblazing/quent that referenced this pull request Jul 13, 2026
…rom_fsm

Rebasing onto main surfaced two integration points:
- main's edits to examples/simulator/analyzer/Cargo.toml overlapped this
  branch's `quent-attributes` addition; the merge silently dropped it,
  breaking the simulator analyzer's rate synthesis. Restore it.
- main added FiniteStateMachine::try_from_fsm (rapidsai#258); populate the new
  attributes / derived_attributes fields there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Felipe Aramburu <felipearamburu@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request New feature or request non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants