Я хотел бы знать, как наилучшим образом объединить два потока, каждый из которых имеет независимые тайм-ауты одинаковой длительности в Rx Java, не вызывая ошибку сбоя.
В Rx Java, если вы запустите В следующем коде вы получите аварийное исключение:
val testObs = Single.fromCallable {
Thread.sleep(10000)
}.subscribeOn(Schedulers.io())
.timeout(5000L, TimeUnit.MILLISECONDS)
.timeout(5000L, TimeUnit.MILLISECONDS)
.test()
testObs.awaitTerminalEvent()
Это потому, что оба эти timeouts
выполняются в потоке computation
, который является или может быть многопоточный . Один из тайм-аутов завершится успешно и отключит поток, а второй вызовет аварийное исключение:
io.reactivex.exceptions.UndeliverableException: исключение не может быть доставлено потребителю, поскольку оно уже отменил / удалил поток или исключение не было go для начала.
Очевидно, одно очевидное решение состоит в том, чтобы не привязывать два таймаута одинаковой длительности к одному потоку.
Однако давайте представим простой класс Api
, который определяет два метода:
fun getNewMessages: Single<List<Messsage>>
fun getUserProfileInfo: Single<Profile>
В вашем коде представьте, что у вас есть отдельные Activity
s, каждый из которых вызывает эти методы независимо; у вас также есть StartupActivity
, который вызывает оба этих метода, но использует Single.zip
для объединения каждой из этих операций, так что он может существенно предварительно извлечь данные и настроить приложение и подготовить его для пользователя. до вызова finish()
экрана запуска spla sh. Реализация каждого из этих методов использует общий сетевой класс, который применяет стандартное значение .timeout
, равное 30 секундам.
К сожалению, если существует проблема с сетью, которая приводит к остановке обоих этих методов за пределами их значения по умолчанию .timeout
значений, а Single.zip
, который объединяет каждую из этих сетевых операций, составит sh.
. Таким образом, существует рекомендуемый шаблон для объединения нескольких сигналов, каждое из которых имеет независимые значения времени ожидания, которые могут быть равны и, следовательно, срабатывать одновременно? Если мы воспользуемся подходом «не добавлять таймауты, если вы не являетесь конечным потребителем», это приведет к большому количеству вставленных копий .timeout(30, TimeUnit.SECOND)
вызовов по всему нашему коду.
Спасибо!