RxJava: interval operator is not returning infinite sequence - rx-java2

As per RxJava documentation, interval operator 'create an Observable that emits a sequence of integers spaced by a given time interval'. I written below program, but the subscribe method is not getting called. Am I missed anything here?
Observable<Long> observable = Observable.interval(1, 1, TimeUnit.SECONDS);
observable.subscribe(new Consumer<Long>() {
#Override
public void accept(Long t) throws Exception {
System.out.println(t);
}
});
I am using 'io.reactivex.rxjava2' version 2.2.6

As I explored, Observable data push is happening in daemon thread, to make my application work, I should hold the main thread for some time, so observable has chance to fire the event. I updated the code like below to make the application run.
Observable<Long> observable = Observable.interval(1, 1, TimeUnit.SECONDS);
observable.subscribe(new Consumer<Long>() {
#Override
public void accept(Long t) throws Exception {
//System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().isDaemon());
System.out.println(t);
}
});
Thread.sleep(5000);

Related

Android Room with RXJava2; onNext() of emitter is not properly triggered

I am switching from async tasks to rxjava2 and have some issues with my code tests.
I have a room table of elements that have a certain monetary amount. On a usercontrol that is called DisplayCurrentBudget, a sum of all amounts should be displayed. This number must refresh everytime a new element is inserted. I tackled the requirement in two ways, but both produce the same result: My code does not care if the database is updated, it only updates when the fragment is recreated (onCreateView).
My first attempt was this:
//RxJava2 Test
Observable<ItemS> ItemObservable = Observable.create( emitter -> {
try {
List<ItemS> movies = oStandardModel.getItemsVanilla();
for (ItemS movie : movies) {
emitter.onNext(movie);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
DisposableObserver<ItemS> disposable = ItemObservable.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribeWith(new DisposableObserver<ItemS>() {
public List<ItemS> BadFeelingAboutThis = new ArrayList<ItemS>();
#Override
public void onNext(ItemS movie) {
// Access your Movie object here
BadFeelingAboutThis.add(movie);
}
#Override
public void onError(Throwable e) {
// Show the user that an error has occurred
}
#Override
public void onComplete() {
// Show the user that the operation is complete
oBinding.DisplayCurrentBudget.setText(Manager.GetBigSum(BadFeelingAboutThis).toString());
}
});
I already was uncomfortable with that code. My second attempt produces the exact same result:
Observable<BigDecimal> ItemObservable2 = Observable.create( emitter -> {
try {
BigDecimal mySum = oStandardModel.getWholeBudget();
emitter.onNext(mySum);
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
DisposableObserver<BigDecimal> disposable = ItemObservable2.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribeWith(new DisposableObserver<BigDecimal>() {
#Override
public void onNext(BigDecimal sum) {
// Access your Movie object here
oBinding.DisplayCurrentBudget.setText(sum.toString());
}
#Override
public void onError(Throwable e) {
// Show the user that an error has occurred
}
#Override
public void onComplete() {
// Show the user that the operation is complete
}
});
Any obvious issues with my code?
Thanks for reading, much appreciate it!
Edit:
I was asked what Manager.GetBigSum does, it actually does not do much. It only adds BigDecimal-Values of an Item list.
public static BigDecimal GetBigSum(List<ItemS> ListP){
List<BigDecimal> bigDList = ListP.stream().map(ItemS::get_dAmount).collect(Collectors.toList());
return bigDList.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
Further, I simplified the query. But it still does not care about DB updates, only about fragment recreation:
Single.fromCallable(() -> oStandardModel.getItemsVanilla())
.map(Manager::GetBigSum)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(e.toString())
);
Your rx logic has no error. That should be internal error in your getWholeBudget.
But why you write rx so complex?
For your case, you can just write:
Single.fromCallable(() -> oStandardModel.getItemsVanilla())
.map(Manager::GetBigSum)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(sum.toString()),
e -> log.error(e));
I solved it this way:
oStandardModel.getItemJointCatLive().observe(this, new Observer<List<ItemJointCat>>() {
#Override
public void onChanged(#Nullable final List<ItemJointCat> oItemSP) {
Single.fromCallable(() -> oStandardModel.getWholeBudget())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(e.toString())
);
}
});
My mistake was that I assumed RXjava2 does not need an onchanged event...now i just use onchanged event of livedata observer to trigger a simple rxjava2 query.
Do you think there is anything wrong with that approach?

Vert.x: Verticle custom startFuture handler is always rewritten

Vert.x v3.5.1.
There is my custom start method of Verticle:
#Override
public void start(Future<Void> startFuture) throws Exception {
startFuture.setHandler(event -> {
if (event.succeeded()) {
logger.info("Server started on port: {}", 8080);
} else {
logger.warn("Failed to start: {}", event.cause());
}
});
vertx.createHttpServer()
.requestHandler(router()::accept)
.listen(8080, event -> {
if (event.succeeded()) {
startFuture.complete();
} else {
startFuture.fail(event.cause());
}
});
}
I expect that my custom handler will be invoked when future completes. But it doesn't!
In debug mode I see that FutureImpl::setHandler is called twice: once with my custom handler, and then with DeploymentManager's handler during doDeploy.
So the latest handler is applied.
The question is: is it possible to specify custom callback for Verticle start? If yes how can I do it?
Thank you in advance.
You're not supposed to change the handler of the startFuture, as it is owned by the caller. So simply, don't do that :) The future is used to signal that you're done with your start-code, and not to define what should be done, once you're done.
In your concrete example it'd be better to write the logs once the http server came up, and then indicate to the startFuture, that you're done with your code execution.
#Override
public void start(Future<Void> startFuture) throws Exception {
vertx.createHttpServer()
.requestHandler(router()::accept)
.listen(8080, event -> {
if (event.succeeded()) {
logger.info("Server started on port: {}", 8080);
startFuture.complete();
} else {
logger.warn("Failed to start: {}", event.cause());
startFuture.fail(event.cause());
}
});
}
At first, write your verticle as a AbstractVerticle extension. And do not override start(Future) method. Instead use start() method. It will be called from AbstractVerticle.start(Future), and you can specify that future in Vertx.deployVerticle(verticle, options, future) method.
For example:
You have some verticle. Do in it start() method only initialization tasks:
#Override
public void start() throws Exception {
vertx.eventbus().consume(address, m -> {
// consumer code skipped
});
}
and verticle registration:
final DeploymentOptions opts = new DeploymentOptions().setWorker(true);
vertx.deployVerticle(verticle, opts, event -> {
if (event.succeeded()) {
log.info("Verticle successfully deployed. DeploymentId: " + event.result());
} else {
log.error("Verticle failed to deploy. Cause: " + event.cause().getMessage(), event.cause());
}
});
That's all :)

Android Mobile Apps query from the azure database returns last row only

There's more than 15 items in my azure database table called Events.
I've tried to run most of the commands found on
https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library such as :
List<Events> results = eventsTable.execute().get()
and
List<Events> results = eventsTable.select("Events").execute().get();
and
List<Events> results = eventsTable.top(20).execute().get();
to return all the row items in the table. The queries seem to run on the last row of the table only and returns the last row or nothing at all when query is executed.
Though the ToDoItem Quickstart from Azure works perfectly with all the queries - which is odd.
Here's some of the code
ArrayList<Events> events = new ArrayLists<Events>();
private void EventsFromTable() {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
try {
final List<Events> results = EventsTable.execute().get();
runOnUiThread(new Runnable() {
#Override
public void run() {
for (Events event : results) {
Events ev = new Events(event.getName(), event.getVenue(), event.getDate());
events.add(ev);
System.out.println("size is " +events.size());
<======This returns "size is 1"======>
}
}
});
} catch (final Exception e){
createAndShowDialogFromTask(e, "Error");
}
return null;
}
};
runAsyncTask(task);
}
Might any one know what the matter is?
Thanks
According to your code, the variable events seems to be a public shared instance of ArraryList in your Android app, so I don't know whether exists the case which multiple threads access it concurrently. The implementation of ArrayList class is not synchronized, please see here.
So please use the code below instead of the code ArrayList<Events> events = new ArrayLists<Events>(); when you shared the variable between UI thread and data async task thread.
List<Events> events = Collections.synchronizedList(new ArrayLists<Events>());
And I think it's better for copying data retrieved from table via addAll method, not add method for each, as the code below.
#Override
public void run() {
events.addAll(results);
}

MongoDB Java Async Driver: Block<Document> vs SingleResultCallBack<Document>

I just started learning mongodb java driver's async API. Most of the examples override SingleResultCallback's onResult method as given bellow:
// get it (since it's the only one in there since we dropped the rest earlier on)
collection.find().first(new SingleResultCallback<Document>() {
#Override
public void onResult(final Document document, final Throwable t) {
System.out.println(document.toJson());
}
});
this callback is executed when the query gets executed and response/error is returned.
But, in case of FindIterable we need to override Block's apply method as 1st argument and SingleResultCallback's onResult method as sencond argument.
FindIterable<Document> iterable = db.getCollection("restaurants").find();
// #code: end
// #pre: Iterate the results and apply a block to each resulting document
// #code: start
iterable.forEach(new Block<Document>() {
#Override
public void apply(final Document document) {
System.out.println(document);
}
}, new SingleResultCallback<Void>() {
#Override
public void onResult(final Void result, final Throwable t) {
System.out.println("Operation Finished");
}
});
I am not able to understand why we need both Block and SingleResultCallBack at the same time. What things/operation can we perform in Block that we couldn't do with SingleResultCallBack?
Block is applied to each item iterated over. SingleResultCallback is executed once the iteration is complete.
The javadoc for com.mongodb.async.client.MongoIterable says:
Iterates over all documents in the view, applying the given block to
each, and completing the returned future after all documents have been
iterated, or an exception has occurred.

empty observable subscribed, but onNext not called?

I want an Observable that doesnt do anything except that when subscribed to, the observer's onNext callback is invoked. I think I found that with Observable.empty(), but the following does not result in the observer's onNext callback being invoked:
Observable<Void> emptyObservable = Observable.empty();
emptyObservable.subscribe(passedinObserver);
passedInObserver was defined:
Observer<Void> passedinObserver = new Observer<Void> {
#Override public void onCompleted() {
}
#Override public void onError(Throwable e) {
}
#Override public void onNext(Void aVoid) {
Log.d("onNext called");
}
};
You can use Observable.just(null) or any value since you are going to ingore the value anyway. However, it appears you want to perform additional work when values travel through an observable sequence, so you can use doOnNext():
Observable.range(1, 10)
.doOnNext(v -> Log.d("onNext called"))
.map(v -> v * v)
.subscribe(System.out::println);
onNext doesn't get called, onCompleted does for this type of Observable.
Alternatively to the other answers, since empty only calls onCompleted without calling onNext, maybe you just want to do your work in onCompleted rather than in onNext?
Try Observable.just(...). It will return one value and thus call .onNext(...).