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:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   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:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   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]

Reply via email to