We are trying to count different things on a Flux. We currently use AtomicIntegers to do the counting, but how can we get these values once the Flux completes? I tried .then
, .collectList().flatMap
and other things, but it seems the Mono I am returning is always created when the AtomicIntegers are still 0. It works if I just subscribe()
on the flux and then return a new Mono, but it doesn't make sense to do so. I even tried it with Mono.defer
but no luck.
Is there a way I am missing?
Not working:
var successCount = new AtomicInteger();
var errorCount = new AtomicInteger();
var filteredRecords = new HashMap<String, List<String>>();
try (var reader = new CSVReader(new InputStreamReader(new ZipInputStream(is)))) {
return Flux.fromIterable(reader)
.map(this::toRecord)
.filter(record -> filterRecords(record, filteredRecords))// add filtered records to a List
.map(this::processRecord)
.doOnNext(result -> successCount.getAndIncrement())// count successfully processed records
.onErrorContinue((ex, record) -> {
log.error(ERROR_RECORD, StructuredArguments.v("record", record), ex);
errorCount.getAndIncrement();
}).collectList().flatMap(resultList -> Mono.defer(() -> checkErrorsAndLog(successCount.get(), errorCount.get(), filteredRecords, fileName)));
//}).then(checkErrorsAndLog(successCount.get(), errorCount.get(), filteredRecords, fileName));// alternate approach
} catch (CsvValidationException | IOException exception) {
log.error(ERROR_LOG_MSG, StructuredArguments.value(FILE_NAME, fileName),
StructuredArguments.value(RECORD_COUNT, 0), exception);
return Mono.error(new ProcessingException(String.format(ERROR_PROCESSING_FAILED, fileName), exception));
}
Only this works:
}).subscribe();
return checkErrorsAndLog(successCount.get(), errorCount.get(), filteredRecords, fileName);