use of io.reactivex.MaybeObserver in project NewPipe by TeamNewPipe.
the class FeedFragment method getChannelInfoObserver.
/**
* On each request, a subscription item from the updated table is transformed
* into a ChannelInfo, containing the latest streams from the channel.
* <p>
* Currently, the feed uses the first into from the list of streams.
* <p>
* If chosen feed already displayed, then we request another feed from another
* subscription, until the subscription table runs out of new items.
* <p>
* This Observer is self-contained and will dispose itself when complete. However, this
* does not obey the fragment lifecycle and may continue running in the background
* until it is complete. This is done due to RxJava2 no longer propagate errors once
* an observer is unsubscribed while the thread process is still running.
* <p>
* To solve the above issue, we can either set a global RxJava Error Handler, or
* manage exceptions case by case. This should be done if the current implementation is
* too costly when dealing with larger subscription sets.
*
* @param url + serviceId to put in {@link #allItemsLoaded} to signal that this specific entity has been loaded.
*/
private MaybeObserver<ChannelInfo> getChannelInfoObserver(final int serviceId, final String url) {
return new MaybeObserver<ChannelInfo>() {
private Disposable observer;
@Override
public void onSubscribe(Disposable d) {
observer = d;
compositeDisposable.add(d);
isLoading.set(true);
}
// Called only when response is non-empty
@Override
public void onSuccess(final ChannelInfo channelInfo) {
if (infoListAdapter == null || channelInfo.getRelatedItems().isEmpty()) {
onDone();
return;
}
final InfoItem item = channelInfo.getRelatedItems().get(0);
// Keep requesting new items if the current one already exists
boolean itemExists = doesItemExist(infoListAdapter.getItemsList(), item);
if (!itemExists) {
infoListAdapter.addInfoItem(item);
// updateSubscription(channelInfo);
} else {
requestFeed(1);
}
onDone();
}
@Override
public void onError(Throwable exception) {
showSnackBarError(exception, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(serviceId), url, 0);
requestFeed(1);
onDone();
}
// Called only when response is empty
@Override
public void onComplete() {
onDone();
}
private void onDone() {
if (observer.isDisposed()) {
return;
}
itemsLoaded.add(serviceId + url);
compositeDisposable.remove(observer);
int loaded = requestLoadedAtomic.incrementAndGet();
if (loaded >= Math.min(FEED_LOAD_COUNT, subscriptionPoolSize)) {
requestLoadedAtomic.set(0);
isLoading.set(false);
}
if (itemsLoaded.size() == subscriptionPoolSize) {
if (DEBUG)
Log.d(TAG, "getChannelInfoObserver > All Items Loaded");
allItemsLoaded.set(true);
showListFooter(false);
isLoading.set(false);
hideLoading();
if (infoListAdapter.getItemsList().size() == 0) {
showEmptyState();
}
}
}
};
}
use of io.reactivex.MaybeObserver in project resilience4j by resilience4j.
the class BulkheadMaybeObserverTest method shouldHonorDisposedWhenCallingOnError.
@Test
public void shouldHonorDisposedWhenCallingOnError() throws Exception {
// Given
Disposable disposable = mock(Disposable.class);
MaybeObserver childObserver = mock(MaybeObserver.class);
MaybeObserver decoratedObserver = BulkheadOperator.of(bulkhead).apply(childObserver);
decoratedObserver.onSubscribe(disposable);
// When
((Disposable) decoratedObserver).dispose();
decoratedObserver.onError(new IllegalStateException());
// Then
verify(childObserver, never()).onError(any());
assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1);
}
use of io.reactivex.MaybeObserver in project resilience4j by resilience4j.
the class BulkheadMaybeObserverTest method shouldNotReleaseBulkheadWhenWasDisposedAfterNotPermittedSubscribe.
@Test
public void shouldNotReleaseBulkheadWhenWasDisposedAfterNotPermittedSubscribe() throws Exception {
// Given
Disposable disposable = mock(Disposable.class);
MaybeObserver childObserver = mock(MaybeObserver.class);
MaybeObserver decoratedObserver = BulkheadOperator.of(bulkhead).apply(childObserver);
bulkhead.isCallPermitted();
assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0);
decoratedObserver.onSubscribe(disposable);
// When
((Disposable) decoratedObserver).dispose();
// Then
assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0);
}
use of io.reactivex.MaybeObserver in project resilience4j by resilience4j.
the class RateLimiterMaybeObserverTest method shouldHonorDisposedWhenCallingOnComplete.
@Test
public void shouldHonorDisposedWhenCallingOnComplete() throws Exception {
// Given
Disposable disposable = mock(Disposable.class);
MaybeObserver childObserver = mock(MaybeObserver.class);
MaybeObserver decoratedObserver = RateLimiterOperator.of(rateLimiter).apply(childObserver);
decoratedObserver.onSubscribe(disposable);
// When
((Disposable) decoratedObserver).dispose();
decoratedObserver.onComplete();
// Then
verify(childObserver, never()).onComplete();
assertSinglePermitUsed();
}
use of io.reactivex.MaybeObserver in project resilience4j by resilience4j.
the class BulkheadMaybeObserverTest method shouldHonorDisposedWhenCallingOnSuccess.
@Test
public void shouldHonorDisposedWhenCallingOnSuccess() throws Exception {
// Given
Disposable disposable = mock(Disposable.class);
MaybeObserver childObserver = mock(MaybeObserver.class);
MaybeObserver decoratedObserver = BulkheadOperator.of(bulkhead).apply(childObserver);
decoratedObserver.onSubscribe(disposable);
// When
((Disposable) decoratedObserver).dispose();
decoratedObserver.onSuccess(1);
// Then
verify(childObserver, never()).onSuccess(any());
assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1);
}
Aggregations