我有一个由几个互连组件组成的系统。一切都运作良好,但经过一段时间后,一些观察者停止接收由观察者的onNext()发送的物品。
简化的场景是这样的:我有
Component1.start()
- >使用Observable.create(...).subscribeOn().observeOn().publish()
创建一个ConnectableObservable,并订阅Component2。之后,它连接()s。这个observable在一个循环中发出一些项目,然后在它完成时调用s.onComplete()
。
Component2实现了Observer。此外,它还有一个运行while(true)循环的ConnectableObservable。当它在由Component1调用的onNext()中获取值时,它使用自己的ConnectableObservable通知Component0。 (注意我也用PublishSubject实现了它们,同样的事情发生了。)
Component1.start() //Creates Component1's ConnectableObservable, subscribes Component2 and starts running with connect();
Component1.connectableObservable -> onNext() ---> Component2
Component2.connectableObservable -> onNext() ---> Component0
当Component0.onNext()获取特定项目(经过100次迭代)后,它会停止Component1.observable,使其退出循环并调用onComplete()。
一段时间后,Component0调用Component1.start(),一切都重新开始。
我看到的是,当一切正常时 Component1.observable.onNext()调用rx.internal.operators.OperatorSubscribeOn.......subscriber.onNext()
rx.internal.operators.OperatorSubscribeOn
@Override
public void call(final Subscriber<? super T> subscriber) {
final Worker inner = scheduler.createWorker();
subscriber.add(inner);
inner.schedule(new Action0() {
@Override
public void call() {
final Thread t = Thread.currentThread();
Subscriber<T> s = new Subscriber<T>(subscriber) {
@Override
public void onNext(T t) {
subscriber.onNext(t);
subscriber.onNext()是内部类private static final class ObserveOnSubscriber<T>
,最后调用schedule():
@Override
public void onNext(final T t) {
if (isUnsubscribed() || finished) {
return;
}
if (!queue.offer(on.next(t))) {
onError(new MissingBackpressureException());
return;
}
schedule();
}
schedule()是
protected void schedule() {
if (counter.getAndIncrement() == 0) {
recursiveScheduler.schedule(this);
}
}
计数器为0,因此调用recursiveScheduler.schedule(this);
并且Component2获取该项目。
现在,当它停止工作时发生的事情是计数器不再是0 ,实际上每次调用都会增加它。因此,recursiveScheduler.schedule(this);
永远不会被调用,而Component2也不会得到任何东西。
这可能是什么原因?为什么计数器0会在某个时刻开始增加?
更新:在源代码中挖掘我见过以下内容:在调用schedule()之后,有一个调度任务调用下面的代码,当项目没有时减少计数器错过:
private static final class ObserveOnSubscriber<T> extends Subscriber<T> implements Action0 {
// only execute this from schedule()
@Override
public void call() {
...
emitted = currentEmission;
missed = counter.addAndGet(-missed);
if (missed == 0L) {
break;
}
据此,由于项目被遗漏,计数器增加,然后后续项目也被遗漏。
错过商品的原因是什么?
我注意到一些奇怪的事情。如果我从程序中删除任何其他(未提及的)可观察量,则不会错过任何项目。他们将Component0作为观察者并在他们自己的subscribeOn()线程中生成他们的项目,所以我看不出它们如何影响这种情况。
更新2:我一直试图找出会发生什么。当我Component1.connectableObservable.connect()
时,它最终会调用private static final class ObserveOnSubscriber<T> extends Subscriber<T> implements Action0 -> init()
这里调用schedule():
void init() {
// don't want this code in the constructor because `this` can escape through the
// setProducer call
Subscriber<? super T> localChild = child;
localChild.setProducer(new Producer() {
@Override
public void request(long n) {
if (n > 0L) {
BackpressureUtils.getAndAddRequest(requested, n);
schedule();
正确的行为在schedule()之后离开OperatorObserveOn.counter = 0。当它不再起作用时,scheduler()会增加+1 OperatorObserveOn.counter的值。
答案 0 :(得分:0)
获取每个订阅的观察者并创建一个监听器,告诉您何时一个观察者取消订阅observable,然后您就可以理解为什么会发生这种情况。
在你的情况下,无论如何我会看看接力,因为你不必取消订阅你的观察它更安全,你可以确定它永远不会停止发射事件。
看看这个例子。
https://github.com/politrons/reactive/blob/master/src/test/java/rx/relay/Relay.java