RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
.observeOn(AndroidSchedulers.mainThread());
Andreas I'm asking because maybe they are into Kotlin and Flow/Coroutines so much that they don't care about RxJava any more.
Flowable.just(message)
.map(mapToSomeObject)
.map(
event -> {
callSomeExternalService(event);
})
.subscribeOn(Schedulers.io())
.doOnNext(
results ->
results.forEach(
result -> {
log.info("Doing things");
dao.update(result);
}))
.doOnError(
error ->
// just logging
log.error(
"There was an error."));
)
.subscribe(
x -> log.info("onNext {}", x),
error -> {
log.error("There was an error in the stream {}", error.getMessage());
},
() -> log.info("onComplete"))
.dispose()
.subscribeOn(Schedulers.io()) it works, otherwise, it seems like it is doing nothing. Any help is appreciated.
subscribe call blocks, so everything completes before dispose is called, but when you subscribe in background thread, subscribe doesn't block, so the subscription is cancelled immediately after creation
Hello all. I'd like to know how can I keep a Flowable emitting items and processing them after an exception occurs. Per my understanding, there are some handlers that may help with it but I tried them all and they are not working. This is very briefly what I'm doing:
Flowable.fromIterable(input)
.map(flowable -> codeThrowingError())
.onErrorResumeNext(err -> Flowable.empty())
.subscribe()However, after the exception is thrown, the pending items in the flowable are not processed. The flow just stop doing things. Is it a way to make this work? TIA.
Flowable.fromIterable(input)
.flatMap(ign -> Flowable.fromCallable(() -> codeThrowingError())
.onErrorResumeNext(err -> Flowable.empty())
)
.subscribe()
Flowable.fromIterable(input)
.flatMap(ign -> Flowable.fromCallable(() -> codeThrowingError())
.onErrorResumeNext(err -> Flowable.empty())
)
. map(x -> moreCodeThatMayThrowAnException()) // here I'd need to add the code to catch the exc again?
.subscribe()
I'm looking for a way of gzipping a Publisher<ByteBuffer> (or Publisher<byte[]> or anything equivalent).
So far I've found that Akka Streams actually has this functionality built-in. These are the helper methods I have right now:
public static Flowable<ByteBuffer> gzip(Publisher<ByteBuffer> bytesPublisher,
int level, Materializer mat) {
final Publisher<akka.util.ByteString> resultPublisher =
Source.fromPublisher(bytesPublisher)
.map(akka.util.ByteString::fromByteBuffer)
.via(akka.stream.javadsl.Compression.gzip(level))
.runWith(Sink.asPublisher(AsPublisher.WITHOUT_FANOUT), mat);
return Flowable.fromPublisher(resultPublisher)
.map(akka.util.ByteString::toByteBuffer);
}
public static Flowable<ByteBuffer> gunzip(Publisher<ByteBuffer> bytesPublisher,
int maxBytesPerChunk, Materializer mat) {
final Publisher<akka.util.ByteString> resultPublisher =
Source.fromPublisher(bytesPublisher)
.map(akka.util.ByteString::fromByteBuffer)
.via(akka.stream.javadsl.Compression.gunzip(maxBytesPerChunk))
.runWith(Sink.asPublisher(AsPublisher.WITHOUT_FANOUT), mat);
return Flowable.fromPublisher(resultPublisher)
.map(akka.util.ByteString::toByteBuffer);
}These are less than elegant because they require a Materializer, which I don't normally use.
So does anyone know of another library that can achieve this in a more elegant way (without the need for something like a Materializer)?
Thanks!
Hello all!. So I want to parallelise an observable and I tried a couple of thins. First:
Flowable.fromIterable(loadSomeValuesFroms3())
.flatMap(value -> Flowable.just(callExternalService(value)
.subscribeOn(Shedulers.io()) // This is expensive so I want run this in parallel.
)
.map(response -> mapToDomainObject(response))
.map(domainObject -> doSomeDomainThing(domainObject))
.map(domainObject -> mapToDTO(domainObject))
.doOnNext(dto -> saveToDB(dto))
.subscribe()And
Flowable.fromIterable(loadSomeValuesFroms3())
.parallel(10)
.map(value -> callExternalService(value)) // This is expensive so I want to run this in parallel.
.map(response -> mapToDomainObject(response))
.map(domainObject -> doSomeDomainThing(domainObject))
.map(domainObject -> mapToDTO(domainObject))
.runOn(Schedullers.io())
.sequential()
.doOnNext(dto -> saveToDB(dto))
.subscribe()I'm reading a csv file that contains 10000 items. But it doesn't seem to be processing that quantity, when I check the db there are about 200 registers. I added an atomic counter as well and the ouput: firstly changes with every new run and secondly is similar to what I have in the DB. I've added counters to errors and it is not consistent trhough runs and it's not even near to the 10000 register I'm expecting to be processed.
.parallel(10) say to 10000 it seems to be processing more registers. I don't see errors with back off or something related to it so I'm kind of lost. I Hope you guys can help me. TIA.
getBigDataPropertiesMessage(textMessage)
.doFirst(() -> logService.setProcessing(monitorTransactionLogId).subscribe())
.flatMap(bigDataMessageDto -> bigDataSender.callBigDataSender(bigDataMessageDto.getMessage(), bigDataMessageDto.getPartitionKey(), bigDataMessageDto.getBigDataEnum()))
.doOnSuccess(response -> {
//do something
logService.setSuccess(monitorTransactionLogId).subscribe();
})
.doOnError(throwable -> {
logService.setError(monitorTransactionLogId, throwable).subscribe();
})
.subscribe();
subscribe's onNext callback of course.
I'm using Spring reactive as a server to make an expensive generation and return the results in Flux one by one. This has the advantage of stopping the generation if the request is cancelled (in cas the constraints and are too tight for example). My code look like this:
public Flux<Entity> generate(int nbrOfEntitiesToGenerate, Constaints constraints) {
return Flux.range(0, nbrOfEntitiesToGenerate)
.map(x -> Generator.expensiveGeneration(constraints)
// .subscribeOn(Schedulers.parallel())
;
}This only does half of what I want, I doesn't make the next call expensiveGeneration when cancelled, but doesn't stop currently running expensive generation that might never finish if the constraints are too tight. How can I do that please.
Extra question if you know, how can I generate x entities in parralel to maximize the use of my threads, (of course without starting ALL the generations at once).
Thanks in advance.
Flux.range(0, 10)
.parallel(4)
.runOn(scheduler)
.map(x -> expensiveGeneration())
.sequential();
expensiveGeneration is not blocking, i.e. it returns a Publisher, then you can do this:Flux.range(0, 10)
.flatMap(x -> expensiveGeneration(), 4);
in the process of evaluating RxJava, i've run into strange behavior while attempting recursion. first, i noticed that RxJava is not stacksafe (please correct me if i'm wrong). second, while attempting to get around the stackoverflow issues, i've gotten into a situation where a very simple program seemingly hangs. here's the bit of code (in Kotlin) i'm working with:
package demos
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.util.concurrent.TimeUnit.SECONDS
fun main() {
fun incr(n: Int): Single<Int> = Single.just(n + 1)
fun numbers(n: Int, max: Int): Flowable<Int> = Flowable.just(n).concatWith(
if (n < max)
incr(n).observeOn(Schedulers.single()).toFlowable().concatMap { next -> numbers(next, max) }
else
Flowable.empty()
)
numbers(1, 1_000_000).sample(5, SECONDS).blockingForEach(::println)
}without the call to .observeOn(Schedulers.single()), the stack explodes... with it, the first few sampled numbers get printed and then... just... nothing, e.g.:
14737
19765
23398
23802would really appreciate any help/advice.