Как я могу исправить состояние гонки в этой наблюдаемой «перезагрузке после времени»? - PullRequest
0 голосов
/ 25 марта 2019

Входные данные - это наблюдаемая, которая выдает значение каждый раз, когда возникает проблема.

В качестве вывода я хочу, чтобы наблюдаемая составляла значение, если проблемы существуют дольше. Другими словами, я хочу «сбросить» наблюдаемый результат (не производить значения), если последняя проблема устарела.

Мое решение:

// first get an observable producing statusOk values (true = ok, false = not ok)
var okStatusObservable = input.Select(_ => true).Throttle(longerTime)
                  .Merge(input.Select(_ => false));


// we only want event if statusOk=false for a longer time
var outputObservable = okStatusObservable
                  .DistinctUntilChanged() // only changes
                  .Throttle(evenLongerTime) // wait for stable status
                  .Where(_ => _ == false); // only interested in bad status

Я думаю, что okStatusObservable может содержать условие гонки: если вход получает события с интервалом времени точно longerTime, а вторая часть слияния (Select / false) выдаст логическое значение перед первой частью (Select + Throttle / true) тогда это приведет к тому, что okStatus будет true 99,9% времени, когда обратное будет правильным.

(PS: чтобы иметь значение статуса с начала, мы могли бы добавить .StartWith(true), но это не имеет значения в отношении состояния расы.)

1 Ответ

2 голосов
/ 25 марта 2019

Более чистый способ сделать первое наблюдаемое заключается в следующем:

var okStatusObservable2 = input
    .Select(_ => Observable.Return(true).Delay(longerTime).StartWith(false))
    .Switch();

Объяснение: Для каждого сообщения input создайте наблюдаемое, которое начинается с false, а после longerTime выдает true,Switch означает, что если у вас есть новая наблюдаемая, просто переключитесь на нее, что исключит полностью прозрачный true в конце.

Для вашей второй наблюдаемой, если longerTime не отличается междудве наблюдаемые, каждая первая false в первой наблюдаемой приведет к false во второй.Это ваше намерение?

Кроме того, ваш Where испорчен (должно быть .Where(b => !b) или .Where(b => b == false). .Where(_ => false) всегда будет иметь значение false, не возвращая ничего.

Кромеэто, я думаю, что ваше решение является правильным.

...