[codex] Add query progress reporting#18649
Conversation
There was a problem hiding this comment.
Pull request overview
Adds end-to-end query progress reporting for long-running Pinot queries, exposing a unified progress model (processed work units / total work units) across SSE (segment-based) and MSE (operator/stage-based) execution paths, and surfacing it via REST/gRPC, Query Console UI, and Pinot CLI.
Changes:
- Introduces
QueryProgressStatsinpinot-spi, plus progress counters inQueryExecutionContext. - Implements progress tracking and retrieval across servers/brokers/controller (including new REST endpoints and a new gRPC
ProgressRPC for MSE). - Adds polling + rendering in Query Console and an interactive CLI progress line / progress bar.
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| pinot-spi/src/test/java/org/apache/pinot/spi/query/QueryProgressStatsTest.java | Adds unit tests for percent calculation, aggregation, JSON round-trip, and execution context accumulation. |
| pinot-spi/src/main/java/org/apache/pinot/spi/query/QueryProgressStats.java | New progress stats model with JSON support, aggregation, and derived percent. |
| pinot-spi/src/main/java/org/apache/pinot/spi/query/QueryExecutionContext.java | Adds atomic progress counters and APIs to mutate/read progress. |
| pinot-server/src/main/java/org/apache/pinot/server/api/resources/QueryResource.java | Adds server REST endpoint to fetch per-query progress and aggregate OFFLINE/REALTIME. |
| pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/executor/OpChainSchedulerServiceTest.java | Adds test coverage for progress tracking on completed op-chains. |
| pinot-query-runtime/src/main/java/org/apache/pinot/query/service/server/QueryServer.java | Adds gRPC Progress RPC handler for MSE worker progress. |
| pinot-query-runtime/src/main/java/org/apache/pinot/query/service/dispatch/QueryDispatcher.java | Adds broker-side dispatch logic to query MSE workers for progress and aggregate responses. |
| pinot-query-runtime/src/main/java/org/apache/pinot/query/service/dispatch/DispatchClient.java | Adds client call implementation for the new gRPC progress RPC. |
| pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/QueryRunner.java | Exposes execution-context tracking and progress retrieval via OpChainSchedulerService. |
| pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/plan/server/ServerPlanRequestUtils.java | Plumbs a shared QueryExecutionContext into leaf-stage ServerQueryRequests for progress attribution. |
| pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/executor/OpChainSchedulerService.java | Tracks execution contexts and increments processed work units on op-chain completion/failure. |
| pinot-core/src/test/java/org/apache/pinot/core/transport/InstanceRequestHandlerTest.java | Updates tests for renamed/cached execution-context retrieval API. |
| pinot-core/src/main/java/org/apache/pinot/core/transport/InstanceRequestHandler.java | Uses cached execution context and exposes server-side progress stats lookup. |
| pinot-core/src/main/java/org/apache/pinot/core/query/scheduler/QueryScheduler.java | Uses cached execution context when opening QueryThreadContext. |
| pinot-core/src/main/java/org/apache/pinot/core/query/request/ServerQueryRequest.java | Adds execution-context caching + setter to support shared context plumbing. |
| pinot-core/src/main/java/org/apache/pinot/core/query/executor/ServerQueryExecutorV1Impl.java | Adds total segment accounting to drive SSE progress denominators. |
| pinot-core/src/main/java/org/apache/pinot/core/operator/combine/SortedGroupByCombineOperator.java | Marks segments as processed during combine execution to advance progress. |
| pinot-core/src/main/java/org/apache/pinot/core/operator/combine/SequentialSortedGroupByCombineOperator.java | Marks segments as processed for sequential sorted group-by combine. |
| pinot-core/src/main/java/org/apache/pinot/core/operator/combine/MinMaxValueBasedSelectionOrderByCombineOperator.java | Marks segments as processed (including skipped segments) for progress accuracy. |
| pinot-core/src/main/java/org/apache/pinot/core/operator/combine/GroupByCombineOperator.java | Marks processed segments during group-by combine. |
| pinot-core/src/main/java/org/apache/pinot/core/operator/combine/BaseSingleBlockCombineOperator.java | Marks segments as processed when producing results blocks. |
| pinot-core/src/main/java/org/apache/pinot/core/operator/combine/BaseCombineOperator.java | Adds shared helper to increment processed-segment progress via thread context. |
| pinot-controller/src/main/resources/app/requests/index.ts | Adds Query Console API call for controller clientQueryId progress endpoint. |
| pinot-controller/src/main/resources/app/pages/Query.tsx | Adds clientQueryId injection, progress polling, and progress UI (numbers + bar). |
| pinot-controller/src/main/resources/app/Models.ts | Adds QueryProgressStats type to UI model definitions. |
| pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotRunningQueryResource.java | Adds controller REST endpoint to fetch progress by clientQueryId by polling brokers. |
| pinot-common/src/main/proto/worker.proto | Adds gRPC Progress RPC and request/response messages for MSE worker progress. |
| pinot-clients/pinot-cli/src/main/java/org/apache/pinot/cli/PinotCli.java | Adds CLI progress polling/rendering, config + flag, and clientQueryId injection. |
| pinot-clients/pinot-cli/README.md | Documents CLI/query-console progress behavior and usage examples. |
| pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java | Tracks MSE execution contexts and aggregates broker+server progress for MSE queries. |
| pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandlerDelegate.java | Routes broker progress requests to MSE handler first, then SSE handler. |
| pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BrokerRequestHandler.java | Extends broker handler interface with getQueryProgressStats(...). |
| pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseSingleStageBrokerRequestHandler.java | Implements SSE progress retrieval by polling servers’ new progress endpoint. |
| pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java | Adds default getQueryProgressStats(...) method stub + precondition for clientQueryId mapping. |
| pinot-broker/src/main/java/org/apache/pinot/broker/api/resources/PinotClientRequest.java | Adds broker REST endpoint to fetch progress by internal requestId or clientQueryId. |
| const progressTimer = window.setInterval(async () => { | ||
| try { | ||
| const response = await getClientQueryProgress(clientQueryId, QUERY_PROGRESS_POLL_INTERVAL_MS); | ||
| setQueryProgress(response.data); | ||
| } catch (error) { | ||
| // The query might not be registered yet, or may already have completed. | ||
| } | ||
| }, QUERY_PROGRESS_POLL_INTERVAL_MS); |
| if (errMsgs.size() > 0) { | ||
| throw new Exception("Unexpected responses from servers: " + StringUtils.join(errMsgs, ",")); | ||
| } | ||
| return serverProgressStats.isEmpty() ? null : QueryProgressStats.aggregate(serverProgressStats); |
| if (errMsgs.size() > 0) { | ||
| throw new Exception("Unexpected responses from brokers: " + StringUtils.join(errMsgs, ",")); | ||
| } | ||
| return null; |
6cb4cc3 to
d601f43
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #18649 +/- ##
============================================
- Coverage 64.39% 64.34% -0.06%
Complexity 1291 1291
============================================
Files 3364 3366 +2
Lines 207935 208439 +504
Branches 32467 32542 +75
============================================
+ Hits 133906 134123 +217
- Misses 63255 63533 +278
- Partials 10774 10783 +9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
d601f43 to
1940943
Compare
xiangfu0
left a comment
There was a problem hiding this comment.
Found one high-signal issue; see inline comment.
1940943 to
5dda15c
Compare
5dda15c to
44ae161
Compare
xiangfu0
left a comment
There was a problem hiding this comment.
Found 1 high-signal issue; see inline comment.
| if (deadline.isExpired()) { | ||
| LOGGER.debug("Timed out waiting for progress response for query: {}", requestId); | ||
| } | ||
| return progressStatsList.isEmpty() ? null : QueryProgressStats.aggregate(progressStatsList); |
There was a problem hiding this comment.
This returns an aggregate over only the servers that responded before the deadline. If one server is still running or transiently unreachable, its unfinished work disappears from the denominator and the broker can report 100% even though the query is still blocked on that server. Please avoid returning a partial aggregate here: either fail/mark progress unknown when any targeted server is missing, or retain last-known totals so missing servers do not shrink the denominator.
Summary
Adds query progress reporting for long-running Pinot queries across the broker, controller, server, V1 execution, V2 execution, query console, and Pinot CLI.
The progress model reports processed work units over total work units. V1 uses server segment progress; V2 estimates work from multi-stage operators and stage execution progress. The controller exposes progress by
clientQueryId, the query console polls it while a query is running, and the CLI can poll and render a single-line progress bar for interactive terminals.User impact
RUNNINGstate.pinot-clisupports--progress-interval-msand config keyprogress-interval-ms.--progress-interval-ms=0and is only rendered for interactive terminals, so redirected output/logs stay clean.Screenshot
Query console progress while a V2 quickstart query is running:
Notes
The CLI injects a generated
clientQueryIdas a quoted query option so progress polling can correlate the client request with running query state.Validation
./mvnw -pl pinot-controller,pinot-clients/pinot-cli -am -DskipTests -DskipITs -Dmaven.javadoc.skip=true compile./mvnw -pl pinot-spi -Dtest=QueryProgressStatsTest test./mvnw -pl pinot-query-runtime -am -Dtest=OpChainSchedulerServiceTest -Dsurefire.failIfNoSpecifiedTests=false test./mvnw -pl pinot-core -am -Dtest=InstanceRequestHandlerTest -Dsurefire.failIfNoSpecifiedTests=false test./mvnw -pl pinot-clients/pinot-cli -DskipTests -DskipITs -Dmaven.javadoc.skip=true packagespotless:apply,license:format,license:check, andcheckstyle:checkon affected modulesgit diff --check