Как лучше всего отлаживать проблемы RxJava с неполученными сообщениями

У меня есть приложение для Android с несколькими наблюдателями типа A, которые подписываются на несколько Observable типа B. Подписка выполняется в IO Scheduler, а наблюдение — в основном потоке Android.

Проблема, с которой я столкнулся, заключается в том, что случайно после некоторой работы одно сообщение, отправленное B, никогда не поступает в A, и после нескольких часов отладки я не могу найти причину.

Соответствующий код когда возникает проблема:

"NEXT1" и "NEXT2" печатаются, а "RECEIVED", "ERROR", COMPLETED - нет.

            //The subscription
            B.getMessate()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(A);

            //B
            Observable<msg> getMessage() {
                 return Observable.create(new Observable.OnSubscribe<msg>() {    
                      public void call(Subscriber<? super msg> subscriber) {
                         ...
                         subscriber.onNext(msg)
                         println("NEXT1")
                      }
                 }).doOnNext({ (o) -> println("NEXT2")});
            }



            //A 
            onNext(msg) {
                  //Never called when problem happens
                  println("RECEIVED")
            }
            onError(msg) {
                  //Never called when problem happens
                  println("ERROR")
            }
            onError(msg) {
                  //Never called when problem happens
                  println("COMPLETED")
            }

Кто-нибудь знает? или какие-либо рекомендации по отладке?

Что я проверил:

  • Я приостановил приложение и проверил все потоки, чтобы увидеть, не заблокирован ли один. И, по-видимому, все рабочие потоки припаркованы, а основной поток ожидает сообщений в очереди сообщений Android.
  • Наблюдатели никогда не вызывают unsubscribe()

person lujop    schedule 15.08.2014    source источник
comment
Я предполагаю, что это просто псевдокод и что вы не вызываете onNext(msg) напрямую в своем методе call, а на самом деле делаете subscribe.onNext(msg)?   -  person Miguel    schedule 16.08.2014
comment
Почему бы вам не дать нам действительно короткий фрагмент кода, который может воспроизвести вашу проблему. Это может облегчить обнаружение проблемы.   -  person Miguel    schedule 16.08.2014
comment
Я исправил псевдокод, вызывающий onNext на подписчике. Что касается предоставления действительно короткого фрагмента кода, проблема заключается в том, что реальный код, который идет перед subscriber.onNext(), большой и сложный. Но я думаю, что это не имеет значения, потому что NEXT2 называется. Как всегда, дьявол кроется в деталях, но этот код — мое лучшее намерение, чтобы ясно проиллюстрировать мою проблему.   -  person lujop    schedule 16.08.2014


Ответы (1)


На данный момент я не могу воспроизвести проблему, но нашел RxJavaDebug очень хороший инструмент для отладки.

Использование простое: добавьте библиотеку как зависимость и при запуске приложения зарегистрируйте слушателя:

  RxJavaPlugins.getInstance().registerObservableExecutionHook(new DebugHook(new DebugNotificationListener() {
      public Object onNext(DebugNotification n) {
          Log.v(TAG, "onNext on " + n);
          return super.onNext(n);
      }


        public Object start(DebugNotification n) {
            Log.v(TAG, "start on " + n);
            return super.start(n);
        }


        public void complete(Object context) {
            Log.v(TAG, "complete on " + context);
        }

        public void error(Object context, Throwable e) {
            Log.e(TAG, "error on " + context);
        }
  }));

Это будет регистрировать сообщения, пока они идут между наблюдаемыми и операторами.

person lujop    schedule 15.08.2014
comment
Что такое DebugHook? Где вы это определяете. - person IgorGanapolsky; 01.04.2016
comment
rx.plugins.DebugHook — это класс RxJava, просто импортируйте его. - person dvtoever; 10.06.2016
comment
Работает ли это с RxJava 2.x? Я видел, что этот проект не обновлялся больше года. - person AsyncMoksha; 20.12.2016
comment
Для меня контекст всегда null. Это должно быть так? Потому что таким образом действительно трудно выяснить, какой наблюдаемый завершился или выдал ошибку. - person ubuntudroid; 23.01.2017
comment
Найдено решение проблемы null: использование rx.plugins.SimpleDebugNotificationListener обеспечивает заполнение контекста. :) - person ubuntudroid; 23.01.2017
comment
@ubuntudroid Вам нужно реализовать какие-либо методы для SimpleDebugNotificationListener? - person WowBow; 05.04.2017
comment
@ZinanXing вы можете использовать RxJava2Debug для RxJava 2.x. Он следует тем же принципам, только упакован и представлен в более приятной форме :) - person Mikel Pascual; 26.09.2017