aliehsaeedii commented on code in PR #22896:
URL: https://github.com/apache/kafka/pull/22896#discussion_r3711340098


##########
docs/streams/developer-guide/interactive-queries.md:
##########
@@ -499,6 +499,198 @@ At this point the full state of the application is 
interactively queryable:
 
 
 
+# Interactive Queries v2 (IQv2) {#interactive-queries-v2}
+
+The sections above describe the original interactive queries API (informally, 
"IQv1"), where you obtain a read-only store facade from 
[KafkaStreams#store(...)](/{version}/javadoc/org/apache/kafka/streams/KafkaStreams.html)
 and call methods such as `get(key)` or `range(from, to)` on it. Interactive 
Queries v2 (IQv2), introduced in 
[KIP-796](https://cwiki.apache.org/confluence/x/34xnCw), is an alternative, 
more flexible API for the same purpose: querying the local state of a running 
Kafka Streams application.
+
+Instead of a fixed store facade, IQv2 models every query as a first-class 
[Query](/{version}/javadoc/org/apache/kafka/streams/query/Query.html) object 
that you submit through a single 
[KafkaStreams#query(StateQueryRequest)](/{version}/javadoc/org/apache/kafka/streams/KafkaStreams.html)
 method. The response is a 
[StateQueryResult](/{version}/javadoc/org/apache/kafka/streams/query/StateQueryResult.html)
 that contains a separate 
[QueryResult](/{version}/javadoc/org/apache/kafka/streams/query/QueryResult.html)
 for each partition that executed the query, along with metadata such as each 
partition's 
[Position](/{version}/javadoc/org/apache/kafka/streams/query/Position.html).
+
+IQv2 offers several advantages over the original API:
+
+  * A single, uniform entry point for every kind of query.
+  * Query-level extensibility: custom state stores can handle their own 
`Query` types (the runtime forwards unknown queries straight through to the 
underlying byte store), rather than requiring a custom `QueryableStoreType` 
store facade as the original API does.
+  * Rich, per-partition results with typed failure reasons instead of 
exceptions.
+  * Fine-grained consistency control through `Position` and `PositionBound`.
+  * The ability to target specific partitions, require active (leader) tasks, 
override the isolation level, and collect execution information.
+
+Both APIs are fully supported and can be used side by side. Note that IQv2 is 
marked as an evolving API, so it may change between releases, and global stores 
are not yet supported by `query(...)` (see [Limitations](#limitations-of-iqv2) 
below).
+
+## How Interactive Queries v2 works
+
+Issuing an IQv2 query follows four steps:
+
+  1. **Build a query.** Create a `Query` object that describes what you want 
to read, for example a 
[KeyQuery](/{version}/javadoc/org/apache/kafka/streams/query/KeyQuery.html) for 
a single-key lookup or a 
[RangeQuery](/{version}/javadoc/org/apache/kafka/streams/query/RangeQuery.html) 
for a scan.
+  2. **Build a request.** Wrap the query in a 
[StateQueryRequest](/{version}/javadoc/org/apache/kafka/streams/query/StateQueryRequest.html)
 that names the store to query: 
`StateQueryRequest.inStore(storeName).withQuery(query)`. Optionally configure 
the request (partitions, position bound, isolation level, and so on).
+  3. **Execute the request.** Call `streams.query(request)`, which runs the 
query against every locally available partition of the store (or just the 
partitions you requested) and returns a `StateQueryResult`.
+  4. **Read the results.** For a query that targets a single partition, use 
`getOnlyPartitionResult()`. For a query that may span multiple partitions, use 
`getPartitionResults()` to get a `Map` from partition number to `QueryResult`. 
Each `QueryResult` reports whether the query succeeded on that partition and 
holds either the result value or a typed failure reason.
+
+## Building and executing a query
+
+The following example looks up a single key in the `CountsKeyValueStore` state 
store from the word-count example used earlier on this page:
+
+```java
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.query.KeyQuery;
+import org.apache.kafka.streams.query.QueryResult;
+import org.apache.kafka.streams.query.StateQueryRequest;
+import org.apache.kafka.streams.query.StateQueryResult;
+
+import static org.apache.kafka.streams.query.StateQueryRequest.inStore;
+
+KafkaStreams streams = ...;
+
+// 1. Build the query: retrieve the value for a single key.
+KeyQuery<String, Long> query = KeyQuery.withKey("alice");
+
+// 2. Build the request, naming the store to run the query against.
+//    A KeyQuery<String, Long> is a Query<Long>, so the request is a 
StateQueryRequest<Long>.
+StateQueryRequest<Long> request = 
inStore("CountsKeyValueStore").withQuery(query);
+
+// 3. Execute the query.
+StateQueryResult<Long> result = streams.query(request);
+
+// 4. Read the result. A given key lives in exactly one partition, so at most 
one partition
+//    returns a value. getOnlyPartitionResult() returns that partition's 
result, or null if
+//    no locally available partition holds the key.
+QueryResult<Long> partitionResult = result.getOnlyPartitionResult();
+if (partitionResult != null && partitionResult.isSuccess()) {
+    Long count = partitionResult.getResult();
+    System.out.println("Count for alice: " + count);
+}
+```
+
+Note that the type parameter of `StateQueryRequest` (and of `StateQueryResult` 
and `QueryResult`) is the query's *result* type, not the query type: a 
`KeyQuery<String, Long>` implements `Query<Long>`, so the request is a 
`StateQueryRequest<Long>`.
+
+## Built-in query types
+
+Kafka Streams ships with a set of query types covering the standard store 
types. All of them live in the 
[org.apache.kafka.streams.query](/{version}/javadoc/org/apache/kafka/streams/query/package-summary.html)
 package.
+
+| Query | Result type (`R`) | Key factory / builder methods |
+| --- | --- | --- |
+| `KeyQuery<K, V>` | `V` | `withKey(key)`; `.skipCache()` |
+| `TimestampedKeyQuery<K, V>` | `ValueAndTimestamp<V>` | `withKey(key)`; 
`.skipCache()` |
+| `RangeQuery<K, V>` | `KeyValueIterator<K, V>` | `withRange(lower, upper)`, 
`withLowerBound(lower)`, `withUpperBound(upper)`, `withNoBounds()`; 
`.withAscendingKeys()` / `.withDescendingKeys()` |
+| `TimestampedRangeQuery<K, V>` | `KeyValueIterator<K, ValueAndTimestamp<V>>` 
| `withRange(lower, upper)`, `withLowerBound(lower)`, `withUpperBound(upper)`, 
`withNoBounds()`; `.withAscendingKeys()` / `.withDescendingKeys()` |
+| `WindowKeyQuery<K, V>` | `WindowStoreIterator<V>` | 
`withKeyAndWindowStartRange(key, timeFrom, timeTo)` |
+| `WindowRangeQuery<K, V>` | `KeyValueIterator<Windowed<K>, V>` | 
`withKey(key)`, `withWindowStartRange(timeFrom, timeTo)` |
+| `VersionedKeyQuery<K, V>` | `VersionedRecord<V>` | `withKey(key)`; 
`.asOf(instant)` |
+| `MultiVersionedKeyQuery<K, V>` | `VersionedRecordIterator<V>` | 
`withKey(key)`; `.fromTime(instant)`, `.toTime(instant)`, 
`.withAscendingTimestamps()` / `.withDescendingTimestamps()` |

Review Comment:
   [completeness — amends my earlier comment on this line] My earlier comment 
asked you to add the four KIP-1356 headers-aware query types to this table. 
That still stands, but the recommendation needs qualifying now that I have 
looked at **#22882**: that PR documents exactly those four types, in this same 
file, in full detail (result semantics, the `*WithHeaders` supplier 
requirement, iterator-closing rules, per-store form restrictions).
   
   So please **don't** write that content again here. Better: add the four rows 
to this table for discoverability and point into #22882's `## Header-aware 
stores and interactive queries` section for the detail — or leave them out of 
the table entirely and link to that section from the paragraph below. Which way 
round depends on the merge order; see the coordination comment on the section 
heading.



##########
docs/streams/developer-guide/interactive-queries.md:
##########
@@ -499,6 +499,198 @@ At this point the full state of the application is 
interactively queryable:
 
 
 
+# Interactive Queries v2 (IQv2) {#interactive-queries-v2}

Review Comment:
   [coordination] This PR and **#22882** ("KAFKA-20682: Document IQv2 
headers-aware queries (KIP-1356)", same author, opened one day earlier) both 
add IQv2 documentation to *this same file*, and neither references the other. 
They overlap in a way git will not catch:
   
   - **Both introduce IQv2 independently.** #22882's `### Reading headers with 
the IQv2 query() API` opens with its own IQv2 primer — build a `Query`, wrap it 
in a `StateQueryRequest`, run `KafkaStreams#query(...)`, read 
`getOnlyPartitionResult()` / `getPartitionResults()` / `getResult()` / 
`getPosition()`. That is the same ground as this PR's "How Interactive Queries 
v2 works" and "Handling query results" sections.
   - **The reading order would be backwards.** #22882 inserts at ~line 375 (a 
`##` under `# Querying local state stores...`); this PR appends at line 502, 
*after* `# Querying remote state stores for the entire app`. Land both as-is 
and the reader meets headers-specific IQv2 detail roughly 130 lines before IQv2 
is introduced at all.
   - **The overlap is editorial, not textual.** Both PRs currently report 
`MERGEABLE` because their hunks sit at different offsets, so both can merge 
cleanly and still leave the page with two IQv2 introductions in the wrong 
order. Nothing will warn you.
   
   Both PRs are drafts today, so there is room to sequence this. Suggested 
resolution: land #22882 (smaller, self-contained, scoped to one KIP), then 
rebase this PR to (a) move this section up to follow `# Querying local state 
stores for an app instance` — which is what my `[order]` comment asks for 
anyway, and which places it *before* the header-aware section — and (b) reduce 
#22882's now-redundant IQv2 primer to a link into this section. The alternative 
is to combine the two into a single coherent restructure of the page.
   
   Either way, worth deciding the split before further review rounds on either 
PR.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to