I have a method that returns an observable. This observable should (if evetything is working right) publish a value each second. What I would like to do is have it publish
I think that the following should work. It uses Throttle
which will wait until 30 seconds have passed with no input before sending anything. You can then merge this with your preexisting source to get your desired behaviour.
var bad = source
.Throttle(TimeSpan.FromSeconds(30))
.Select(_ => "bad");
var merged = source.Merge(bad);
Here is a way. Starts a timer which will yield "bad" when it expires. Each time your statusProvider produces a status, the timer gets reset.
var statusSignal = statusProvider
.Subscribe(statusKey) //returns an IObservable<string>
.Select(st => st.ToUpper())
.Publish()
.RefCount();
// An observable that produces "bad" after a delay and then "hangs indefinately" after that
var badTimer = Observable
.Return("bad")
.Delay(TimeSpan.FromSeconds(30))
.Concat(Observable.Never<string>());
// A repeating badTimer that resets the timer whenever a good signal arrives.
// The "indefinite hang" in badTimer prevents this from restarting the timer as soon
// as it produces a "bad". Which prevents you from getting a string of "bad" messages
// if the statusProvider is silent for many minutes.
var badSignal = badTimer.TakeUntil(statusSignal).Repeat();
// listen to both good and bad signals.
return Observable
.Merge(statusSignal, badSignal)
.DistinctUntilChanged()
.Replay(1)
.RefCount();