I am using spring webflux with reactor and I have the following flux for uploading images, resizing them and storing them. For each size I execute the described flux in parallel on a custom executor service.
Any of the methods createDbAttachmentEntity, resizeAttachment, storeFile can throw various exceptions.
Executing the resizing in parallel means that any thread involved may throw exception. That means I need to rollback all the changes in case something was not properly executed.
For example I may have 5 sizes but in DB the system added only 4 and 5 are expected. Or I may have an error in converting my streams. Or I may have an error in the storage system.
In case of exception I would like to be able to rollback all the changes (manually delete database entries and manually delete the files.
How can I do that?
Flux.just(sizes)
.parallel()
.runOn(Schedulers.fromExecutor(executorService))
.map(size -> createDbAttachmentEntity(size))
.map(size_attachment -> resizeAttachment(size_attachment.getT1(), originalBytes))
.map(size_attachment_bytes -> storeFile(...))
.sequential()
.collectList()
.map(list -> {
if(list.size() != sizes.length
|| list.stream().anyMatch(objects -> objects.getT2().getId() == null)) {
throw new RuntimeException();
}
return list;
})
.flux()
here .onErrorReturn(.......deleteEntities...........deleteFiles...........) // problem: I do not have the files/entities
.flatMap(list -> Flux.fromStream(list.stream()))
.collectMap(Tuple2::getT1, Tuple2::getT2);
I was thinking about solving it with this but it doesn't work
Flux.just(1, 2, 3, 4, 5, 6, 7)
.map(integer -> {
if (integer == 3) throw new RuntimeException("3");
return integer;
})
.flatMap(integer -> Flux.just(integer)
.onErrorResume(t -> {
System.out.println("--onErrorResume" + integer); // here is what I need to pass in
return Flux.empty();
}))