hlteoh37 commented on code in PR #195:
URL: 
https://github.com/apache/flink-connector-aws/pull/195#discussion_r2042593349


##########
flink-connector-aws/flink-connector-aws-kinesis-streams/src/main/java/org/apache/flink/connector/kinesis/source/reader/KinesisShardSplitReaderBase.java:
##########
@@ -125,6 +144,52 @@ public RecordsWithSplitIds<Record> fetch() throws 
IOException {
                 recordBatch.isCompleted());
     }
 
+    private boolean skipWhenNoAssignedSplit(KinesisShardSplitState splitState) 
throws IOException {
+        if (splitState == null) {
+            try {
+                // Small sleep to prevent busy polling
+                Thread.sleep(1);
+                return true;
+            } catch (InterruptedException e) {
+                throw new IOException("Sleep was interrupted while skipping no 
assigned split", e);
+            }
+        }
+
+        return false;
+    }
+
+    private boolean skipUntilScheduledFetchTime(KinesisShardSplitState 
splitState)
+            throws IOException {
+        if (scheduledFetchTimes.containsKey(splitState)
+                && scheduledFetchTimes.get(splitState) > 
System.currentTimeMillis()) {
+            try {
+                // Small sleep to prevent busy polling
+                Thread.sleep(1);
+                return true;
+            } catch (InterruptedException e) {
+                throw new IOException(

Review Comment:
   Same as above, we should propagate the interrupted status up the thread.



##########
flink-connector-aws/flink-connector-aws-kinesis-streams/src/main/java/org/apache/flink/connector/kinesis/source/reader/KinesisShardSplitReaderBase.java:
##########
@@ -125,6 +144,52 @@ public RecordsWithSplitIds<Record> fetch() throws 
IOException {
                 recordBatch.isCompleted());
     }
 
+    private boolean skipWhenNoAssignedSplit(KinesisShardSplitState splitState) 
throws IOException {
+        if (splitState == null) {
+            try {
+                // Small sleep to prevent busy polling
+                Thread.sleep(1);
+                return true;
+            } catch (InterruptedException e) {
+                throw new IOException("Sleep was interrupted while skipping no 
assigned split", e);
+            }
+        }
+
+        return false;
+    }
+
+    private boolean skipUntilScheduledFetchTime(KinesisShardSplitState 
splitState)
+            throws IOException {
+        if (scheduledFetchTimes.containsKey(splitState)
+                && scheduledFetchTimes.get(splitState) > 
System.currentTimeMillis()) {
+            try {
+                // Small sleep to prevent busy polling
+                Thread.sleep(1);
+                return true;
+            } catch (InterruptedException e) {
+                throw new IOException(
+                        "Sleep was interrupted while skipping until scheduled 
fetch record time",
+                        e);
+            }
+        }
+
+        return false;
+    }
+
+    private void scheduleNextFetchTime(KinesisShardSplitState splitState, 
RecordBatch recordBatch) {

Review Comment:
   Let's add a javadoc to explain how we expect "scheduledFetchTimes" to be 
used.
   
   1/ If split was not active, we will schedule fetch time. We will wait until 
next fetch time before polling.
   2/ If split was active, we will NOT schedule a fetch time. We should 
immediately poll.
   
   (Num. 2 is not intuitive)



##########
flink-connector-aws/flink-connector-aws-kinesis-streams/src/main/java/org/apache/flink/connector/kinesis/source/reader/KinesisShardSplitReaderBase.java:
##########
@@ -125,6 +144,52 @@ public RecordsWithSplitIds<Record> fetch() throws 
IOException {
                 recordBatch.isCompleted());
     }
 
+    private boolean skipWhenNoAssignedSplit(KinesisShardSplitState splitState) 
throws IOException {
+        if (splitState == null) {
+            try {
+                // Small sleep to prevent busy polling
+                Thread.sleep(1);
+                return true;
+            } catch (InterruptedException e) {
+                throw new IOException("Sleep was interrupted while skipping no 
assigned split", e);

Review Comment:
   We should propagate the interrupted status up the thread.
   ```
   Thread.interrupt()
   ```



##########
flink-connector-aws/flink-connector-aws-kinesis-streams/src/test/java/org/apache/flink/connector/kinesis/source/reader/PollingKinesisShardSplitReaderTest.java:
##########
@@ -395,6 +399,79 @@ void testMaxRecordsToGetParameterPassed() throws 
IOException {
         assertThat(records.size()).isEqualTo(maxRecordsToGet);
     }
 
+    @ValueSource(longs = {0L, 250L, 1000L})
+    @ParameterizedTest
+    public void testGetRecordsIntervalForIdleSource(long interval) {
+        Configuration configuration = newConfigurationForTest();
+        configuration.set(READER_EMPTY_RECORDS_FETCH_INTERVAL, 
Duration.ofMillis(interval));
+
+        splitReader =
+                new PollingKinesisShardSplitReader(
+                        testStreamProxy, shardMetricGroupMap, configuration);
+
+        testStreamProxy.addShards(TEST_SHARD_ID);
+        splitReader.handleSplitsChanges(
+                new 
SplitsAddition<>(Collections.singletonList(getTestSplit(TEST_SHARD_ID))));
+
+        await().atLeast(interval, TimeUnit.MILLISECONDS)
+                .atMost(interval + 250, TimeUnit.MILLISECONDS)
+                .pollInSameThread()
+                .pollInterval(Duration.ofMillis(1))
+                .untilAsserted(
+                        () -> {
+                            
assertThat(splitReader.fetch().nextRecordFromSplit()).isNull();
+                            
assertThat(testStreamProxy.getTotalGetRecordsCall()).isEqualTo(2);
+                        });
+    }
+
+    @ValueSource(ints = {1, 8, 64})
+    @ParameterizedTest
+    public void testGetRecordsIntervalForMultipleIdleSource(int shardCount) {

Review Comment:
   easy to read :) 



##########
flink-connector-aws/flink-connector-aws-kinesis-streams/src/test/java/org/apache/flink/connector/kinesis/source/reader/fanout/FanOutKinesisShardSplitReaderTest.java:
##########
@@ -31,32 +32,48 @@
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import software.amazon.awssdk.services.kinesis.model.Record;
 
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
+import static 
org.apache.flink.connector.kinesis.source.config.KinesisSourceConfigOptions.EFO_CONSUMER_SUBSCRIPTION_TIMEOUT;
+import static 
org.apache.flink.connector.kinesis.source.config.KinesisSourceConfigOptions.READER_EMPTY_RECORDS_FETCH_INTERVAL;
 import static 
org.apache.flink.connector.kinesis.source.util.TestUtil.CONSUMER_ARN;
+import static 
org.apache.flink.connector.kinesis.source.util.TestUtil.generateShardId;
 import static 
org.apache.flink.connector.kinesis.source.util.TestUtil.getTestSplit;
 import static 
org.assertj.core.api.AssertionsForClassTypes.assertThatNoException;
 import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.awaitility.Awaitility.await;
 import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;

Review Comment:
   Why do we need to test the await behaviour here? Since we are testing the 
behaviour of the `KinesisShardSplitReaderBase`, can we instead 
   
   1/ Implement a no-op test implementation of the base, and test that? That 
way we scope it directly to the abstract class being tested.



##########
flink-connector-aws/flink-connector-aws-kinesis-streams/src/test/java/org/apache/flink/connector/kinesis/source/reader/fanout/FanOutKinesisShardSplitReaderTest.java:
##########
@@ -31,32 +32,48 @@
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import software.amazon.awssdk.services.kinesis.model.Record;
 
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
+import static 
org.apache.flink.connector.kinesis.source.config.KinesisSourceConfigOptions.EFO_CONSUMER_SUBSCRIPTION_TIMEOUT;
+import static 
org.apache.flink.connector.kinesis.source.config.KinesisSourceConfigOptions.READER_EMPTY_RECORDS_FETCH_INTERVAL;
 import static 
org.apache.flink.connector.kinesis.source.util.TestUtil.CONSUMER_ARN;
+import static 
org.apache.flink.connector.kinesis.source.util.TestUtil.generateShardId;
 import static 
org.apache.flink.connector.kinesis.source.util.TestUtil.getTestSplit;
 import static 
org.assertj.core.api.AssertionsForClassTypes.assertThatNoException;
 import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.awaitility.Awaitility.await;
 import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;

Review Comment:
   We shouldn't be using Mockito - Flink best practices is to implement test 
classes to mimic interface behavior



-- 
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