gemini-code-assist[bot] commented on code in PR #37691:
URL: https://github.com/apache/beam/pull/37691#discussion_r2843507744
##########
sdks/java/harness/src/main/java/org/apache/beam/fn/harness/state/StateFetchingIterators.java:
##########
@@ -669,12 +675,23 @@ static class LazyBlockingStateFetchingIterator implements
PrefetchableIterator<B
private final StateRequest stateRequestForFirstChunk;
private ByteString continuationToken;
private CompletableFuture<StateResponse> prefetchedResponse;
+ private boolean hasNoState;
LazyBlockingStateFetchingIterator(
BeamFnStateClient beamFnStateClient, StateRequest
stateRequestForFirstChunk) {
this.beamFnStateClient = beamFnStateClient;
this.stateRequestForFirstChunk = stateRequestForFirstChunk;
this.continuationToken =
stateRequestForFirstChunk.getGet().getContinuationToken();
+ this.hasNoState = false;
+ }
+
+ LazyBlockingStateFetchingIterator(
+ BeamFnStateClient beamFnStateClient, StateRequest
stateRequestForFirstChunk,
+ boolean hasNoState) {
+ this.beamFnStateClient = beamFnStateClient;
+ this.stateRequestForFirstChunk = stateRequestForFirstChunk;
+ this.continuationToken =
stateRequestForFirstChunk.getGet().getContinuationToken();
+ this.hasNoState = hasNoState;
}
Review Comment:

There's a potential `NullPointerException` here. If `hasNoState` is true,
`continuationToken` can still be non-null (e.g., `ByteString.EMPTY` for a new
read). This would cause `hasNext()` to return `true`. However, `prefetch()`
will do nothing due to the `!hasNoState` check. Consequently, when `next()` is
called, it will attempt to call `.get()` on a `null` `prefetchedResponse`,
leading to an NPE.
To fix this, the iterator should be made empty when `hasNoState` is true.
The cleanest way to achieve this is by setting `continuationToken` to `null` in
the constructor if `hasNoState` is true. This will cause `hasNext()` to return
`false` from the beginning.
```java
LazyBlockingStateFetchingIterator(
BeamFnStateClient beamFnStateClient, StateRequest
stateRequestForFirstChunk,
boolean hasNoState) {
this.beamFnStateClient = beamFnStateClient;
this.stateRequestForFirstChunk = stateRequestForFirstChunk;
this.hasNoState = hasNoState;
if (hasNoState) {
this.continuationToken = null;
} else {
this.continuationToken =
stateRequestForFirstChunk.getGet().getContinuationToken();
}
}
```
##########
sdks/java/harness/src/main/java/org/apache/beam/fn/harness/state/StateFetchingIterators.java:
##########
@@ -713,7 +730,7 @@ public boolean isReady() {
@Override
public void prefetch() {
- if (continuationToken != null && prefetchedResponse == null) {
+ if (continuationToken != null && prefetchedResponse == null &&
!hasNoState) {
Review Comment:

If the constructor is updated to nullify `continuationToken` when
`hasNoState` is true (as suggested in another comment), this `!hasNoState`
check becomes redundant because `continuationToken != null` will already be
false in that case. You could simplify this condition for better readability.
```java
if (continuationToken != null && prefetchedResponse == null) {
```
--
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]