@@ -63,19 +63,23 @@ public class DefaultStreamPoller implements StreamPoller {
63
63
@ Nullable
64
64
private IngestionShardPointer maxPersistedPointer ;
65
65
66
+ private IngestionErrorStrategy errorStrategy ;
67
+
66
68
public DefaultStreamPoller (
67
69
IngestionShardPointer startPointer ,
68
70
Set <IngestionShardPointer > persistedPointers ,
69
71
IngestionShardConsumer consumer ,
70
72
IngestionEngine ingestionEngine ,
71
- ResetState resetState
73
+ ResetState resetState ,
74
+ IngestionErrorStrategy errorStrategy
72
75
) {
73
76
this (
74
77
startPointer ,
75
78
persistedPointers ,
76
79
consumer ,
77
- new MessageProcessorRunnable (new ArrayBlockingQueue <>(100 ), ingestionEngine ),
78
- resetState
80
+ new MessageProcessorRunnable (new ArrayBlockingQueue <>(100 ), ingestionEngine , errorStrategy ),
81
+ resetState ,
82
+ errorStrategy
79
83
);
80
84
}
81
85
@@ -84,7 +88,8 @@ public DefaultStreamPoller(
84
88
Set <IngestionShardPointer > persistedPointers ,
85
89
IngestionShardConsumer consumer ,
86
90
MessageProcessorRunnable processorRunnable ,
87
- ResetState resetState
91
+ ResetState resetState ,
92
+ IngestionErrorStrategy errorStrategy
88
93
) {
89
94
this .consumer = Objects .requireNonNull (consumer );
90
95
this .resetState = resetState ;
@@ -109,6 +114,7 @@ public DefaultStreamPoller(
109
114
String .format (Locale .ROOT , "stream-poller-processor-%d-%d" , consumer .getShardId (), System .currentTimeMillis ())
110
115
)
111
116
);
117
+ this .errorStrategy = errorStrategy ;
112
118
}
113
119
114
120
@ Override
@@ -133,6 +139,9 @@ protected void startPoll() {
133
139
}
134
140
logger .info ("Starting poller for shard {}" , consumer .getShardId ());
135
141
142
+ // track the last record successfully written to the blocking queue
143
+ IngestionShardPointer lastSuccessfulPointer = null ;
144
+
136
145
while (true ) {
137
146
try {
138
147
if (closed ) {
@@ -188,6 +197,7 @@ protected void startPoll() {
188
197
continue ;
189
198
}
190
199
blockingQueue .put (result );
200
+ lastSuccessfulPointer = result .getPointer ();
191
201
logger .debug (
192
202
"Put message {} with pointer {} to the blocking queue" ,
193
203
String .valueOf (result .getMessage ().getPayload ()),
@@ -197,8 +207,18 @@ protected void startPoll() {
197
207
// update the batch start pointer to the next batch
198
208
batchStartPointer = consumer .nextPointer ();
199
209
} catch (Throwable e ) {
200
- // TODO better error handling
201
210
logger .error ("Error in polling the shard {}: {}" , consumer .getShardId (), e );
211
+ errorStrategy .handleError (e , IngestionErrorStrategy .ErrorStage .POLLING );
212
+
213
+ if (errorStrategy .shouldPauseIngestion (e , IngestionErrorStrategy .ErrorStage .POLLING )) {
214
+ // Blocking error encountered. Pause poller to stop processing remaining updates.
215
+ pause ();
216
+ } else {
217
+ // Advance the batch start pointer to ignore the error and continue from next record
218
+ batchStartPointer = lastSuccessfulPointer == null
219
+ ? consumer .nextPointer (batchStartPointer )
220
+ : consumer .nextPointer (lastSuccessfulPointer );
221
+ }
202
222
}
203
223
}
204
224
}
0 commit comments