|
65 | 65 | import org.springframework.context.ApplicationEventPublisherAware;
|
66 | 66 | import org.springframework.core.AttributeAccessor;
|
67 | 67 | import org.springframework.core.convert.converter.Converter;
|
68 |
| -import org.springframework.core.log.LogMessage; |
69 | 68 | import org.springframework.core.serializer.support.DeserializingConverter;
|
70 | 69 | import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
71 | 70 | import org.springframework.integration.aws.event.KinesisShardEndedEvent;
|
@@ -1146,36 +1145,42 @@ private Runnable processTask() {
|
1146 | 1145 | }
|
1147 | 1146 |
|
1148 | 1147 | private void rewindIteratorOnError(Exception ex, GetRecordsResponse result) {
|
1149 |
| - KinesisShardOffset newOffset = new KinesisShardOffset(this.shardOffset); |
1150 | 1148 | String lastCheckpoint = this.checkpointer.getLastCheckpointValue();
|
1151 | 1149 | String highestSequence = this.checkpointer.getHighestSequence();
|
1152 |
| - if (highestSequence.equals(lastCheckpoint)) { |
| 1150 | + |
| 1151 | + if (highestSequence == null) { |
| 1152 | + // Haven't reached record process - reuse the current shard iterator. |
| 1153 | + logger.info(ex, "getRecords request has thrown exception. " + |
| 1154 | + "No checkpoints - re-request with the current shard iterator."); |
| 1155 | + } |
| 1156 | + else if (highestSequence.equals(lastCheckpoint)) { |
1153 | 1157 | logger.info(ex, "Record processor has thrown exception. " +
|
1154 | 1158 | "Ignore since the highest sequence in batch was check-pointed.");
|
1155 | 1159 | this.shardIterator = result.nextShardIterator();
|
1156 |
| - return; |
1157 | 1160 | }
|
1158 |
| - String newOffsetValue = lastCheckpoint; |
1159 |
| - if (lastCheckpoint != null) { |
1160 |
| - newOffset.setIteratorType(ShardIteratorType.AFTER_SEQUENCE_NUMBER); |
| 1161 | + else if (lastCheckpoint == null |
| 1162 | + || new BigInteger(lastCheckpoint).compareTo(new BigInteger(this.shardIterator)) < 0) { |
| 1163 | + |
| 1164 | + // No checkpoints for the shard - reuse the current shard iterator. |
| 1165 | + logger.info(ex, "Record processor has thrown exception. " + |
| 1166 | + "No checkpoints - re-request with the current shard iterator."); |
1161 | 1167 | }
|
1162 | 1168 | else {
|
1163 |
| - newOffsetValue = this.checkpointer.getFirstSequenceInBatch(); |
1164 |
| - newOffset.setIteratorType(ShardIteratorType.AT_SEQUENCE_NUMBER); |
1165 |
| - } |
1166 |
| - |
1167 |
| - logger.info(ex, |
1168 |
| - LogMessage.format("Record processor has thrown exception. " + |
1169 |
| - "Rewind shard iterator %s sequence number: %s", |
1170 |
| - (lastCheckpoint != null ? "after" : "at"), newOffsetValue)); |
| 1169 | + KinesisShardOffset newOffset = new KinesisShardOffset(this.shardOffset); |
| 1170 | + newOffset.setIteratorType(ShardIteratorType.AFTER_SEQUENCE_NUMBER); |
1171 | 1171 |
|
1172 |
| - newOffset.setSequenceNumber(newOffsetValue); |
1173 |
| - GetShardIteratorRequest shardIteratorRequest = newOffset.toShardIteratorRequest(); |
1174 |
| - this.shardIterator = |
1175 |
| - KinesisMessageDrivenChannelAdapter.this.amazonKinesis |
1176 |
| - .getShardIterator(shardIteratorRequest) |
1177 |
| - .join() |
1178 |
| - .shardIterator(); |
| 1172 | + logger.info(ex, () -> |
| 1173 | + "Record processor has thrown exception. " + |
| 1174 | + "Rewind shard iterator after sequence number: " + lastCheckpoint); |
| 1175 | + |
| 1176 | + newOffset.setSequenceNumber(lastCheckpoint); |
| 1177 | + GetShardIteratorRequest shardIteratorRequest = newOffset.toShardIteratorRequest(); |
| 1178 | + this.shardIterator = |
| 1179 | + KinesisMessageDrivenChannelAdapter.this.amazonKinesis |
| 1180 | + .getShardIterator(shardIteratorRequest) |
| 1181 | + .join() |
| 1182 | + .shardIterator(); |
| 1183 | + } |
1179 | 1184 | }
|
1180 | 1185 |
|
1181 | 1186 | private void checkpointSwallowingProvisioningExceptions(String endingSequenceNumber) {
|
@@ -1235,7 +1240,6 @@ private void prepareSleepState() {
|
1235 | 1240 | private void processRecords(List<Record> records) {
|
1236 | 1241 | logger.trace(() -> "Processing records: " + records + " for [" + ShardConsumer.this + "]");
|
1237 | 1242 |
|
1238 |
| - this.checkpointer.setFirstSequenceInBatch(records.get(0).sequenceNumber()); |
1239 | 1243 | this.checkpointer.setHighestSequence(records.get(records.size() - 1).sequenceNumber());
|
1240 | 1244 |
|
1241 | 1245 | if (ListenerMode.record.equals(KinesisMessageDrivenChannelAdapter.this.listenerMode)) {
|
|
0 commit comments