13
13
14
14
package com .rabbitmq .stream .impl ;
15
15
16
+ import static com .rabbitmq .stream .impl .Utils .offsetBefore ;
17
+
16
18
import com .rabbitmq .stream .Constants ;
17
19
import com .rabbitmq .stream .MessageHandler .Context ;
18
20
import com .rabbitmq .stream .StreamException ;
25
27
import java .util .concurrent .ScheduledExecutorService ;
26
28
import java .util .concurrent .TimeUnit ;
27
29
import java .util .concurrent .atomic .AtomicBoolean ;
30
+ import java .util .concurrent .atomic .AtomicLong ;
28
31
import java .util .function .Consumer ;
29
32
import java .util .function .LongConsumer ;
30
33
import org .slf4j .Logger ;
@@ -176,7 +179,7 @@ private static final class AutoTrackingTracker implements Tracker {
176
179
private final long flushIntervalInNs ;
177
180
private final LocalClock clock ;
178
181
private volatile long count = 0 ;
179
- private volatile long lastProcessedOffset = 0 ;
182
+ private volatile AtomicLong lastProcessedOffset = null ;
180
183
private volatile long lastTrackingActivity = 0 ;
181
184
182
185
private AutoTrackingTracker (
@@ -193,24 +196,31 @@ public Consumer<Context> postProcessingCallback() {
193
196
context .storeOffset ();
194
197
lastTrackingActivity = clock .time ();
195
198
}
196
- lastProcessedOffset = context .offset ();
199
+ if (lastProcessedOffset == null ) {
200
+ lastProcessedOffset = new AtomicLong (context .offset ());
201
+ } else {
202
+ lastProcessedOffset .set (context .offset ());
203
+ }
197
204
};
198
205
}
199
206
200
207
public void flushIfNecessary () {
201
208
if (this .count > 0 ) {
202
209
if (this .clock .time () - this .lastTrackingActivity > this .flushIntervalInNs ) {
203
- try {
204
- long lastStoredOffset = consumer .lastStoredOffset ();
205
- if (Long .compareUnsigned (lastStoredOffset , lastProcessedOffset ) < 0 ) {
206
- this .consumer .store (this .lastProcessedOffset );
210
+ if (lastProcessedOffset != null ) {
211
+ try {
212
+ long lastStoredOffset = consumer .lastStoredOffset ();
213
+ if (offsetBefore (lastStoredOffset , lastProcessedOffset .get ())) {
214
+ this .consumer .store (this .lastProcessedOffset .get ());
215
+ }
207
216
this .lastTrackingActivity = clock .time ();
208
- }
209
- } catch (StreamException e ) {
210
- if (e .getCode () == Constants .RESPONSE_CODE_NO_OFFSET ) {
211
- // probably nothing stored yet, let it go
212
- } else {
213
- throw e ;
217
+ } catch (StreamException e ) {
218
+ if (e .getCode () == Constants .RESPONSE_CODE_NO_OFFSET ) {
219
+ this .consumer .store (this .lastProcessedOffset .get ());
220
+ this .lastTrackingActivity = clock .time ();
221
+ } else {
222
+ throw e ;
223
+ }
214
224
}
215
225
}
216
226
}
@@ -230,22 +240,21 @@ public LongConsumer trackingCallback() {
230
240
@ Override
231
241
public Runnable closingCallback () {
232
242
return () -> {
233
- try {
234
- long lastStoredOffset = consumer .lastStoredOffset ();
235
- if (Long .compareUnsigned (lastStoredOffset , lastProcessedOffset ) < 0 ) {
236
- LOGGER .debug ("Storing offset before closing" );
237
- this .consumer .store (this .lastProcessedOffset );
238
- } else {
239
- LOGGER .debug (
240
- "Not storing offset before closing because last stored offset after last processed offset: {} > {}" ,
241
- lastStoredOffset ,
242
- lastProcessedOffset );
243
- }
244
- } catch (StreamException e ) {
245
- if (e .getCode () == Constants .RESPONSE_CODE_NO_OFFSET ) {
246
- // probably nothing stored yet, let it go
247
- } else {
248
- throw e ;
243
+ if (this .lastProcessedOffset == null ) {
244
+ LOGGER .debug ("Not storing anything as nothing has been processed." );
245
+ } else {
246
+ try {
247
+ long lastStoredOffset = consumer .lastStoredOffset ();
248
+ if (offsetBefore (lastStoredOffset , lastProcessedOffset .get ())) {
249
+ LOGGER .debug ("Storing {} offset before closing" , this .lastProcessedOffset );
250
+ this .consumer .store (this .lastProcessedOffset .get ());
251
+ }
252
+ } catch (StreamException e ) {
253
+ if (e .getCode () == Constants .RESPONSE_CODE_NO_OFFSET ) {
254
+ LOGGER .debug (
255
+ "Nothing stored yet, storing {} offset before closing" , this .lastProcessedOffset );
256
+ this .consumer .store (this .lastProcessedOffset .get ());
257
+ }
249
258
}
250
259
}
251
260
};
@@ -277,13 +286,14 @@ public void flushIfNecessary() {
277
286
if (this .clock .time () - this .lastTrackingActivity > this .checkIntervalInNs ) {
278
287
try {
279
288
long lastStoredOffset = consumer .lastStoredOffset ();
280
- if (Long . compareUnsigned (lastStoredOffset , lastRequestedOffset ) < 0 ) {
289
+ if (offsetBefore (lastStoredOffset , lastRequestedOffset )) {
281
290
this .consumer .store (this .lastRequestedOffset );
282
291
this .lastTrackingActivity = clock .time ();
283
292
}
284
293
} catch (StreamException e ) {
285
294
if (e .getCode () == Constants .RESPONSE_CODE_NO_OFFSET ) {
286
- // probably nothing stored yet, let it go
295
+ this .consumer .store (this .lastRequestedOffset );
296
+ this .lastTrackingActivity = clock .time ();
287
297
} else {
288
298
throw e ;
289
299
}
0 commit comments