2

I need to combine two observables which usually produce values one after the other. The first sequence (let's call it Seq A) produces more values than the second (Seq B), but usually a bunch of values from the first observable are follewed by one value on the second. So basically I need to produce a value from the latest value of Seq A and the latest of Seq B.

However, it can happen that the second sequence doesn't produce a value. In that case, the combined sequence should still produce a value; when after a value from SeqA and some timeout Seq B still didn't produce a value, I need to produce a value from just Seq A.

The marble diagram should look like this:

                          <-> Timeout          No timeout
Seq A  | a1-----------a2a3---------------a4a5-a6---------
Seq B  | --b1----------------------------------b3--------
Output | ---x1--------------x2------------------x3-------
                            ^ - I need this      ^ - And this

where Output basically is some combination of the values.

PS: I have a hard time explaining the problem consisely, so please excuse the title.

Sammy S.
  • 1,280
  • 1
  • 16
  • 31
  • So, in more layman terms - you want to produce a value from sequence B if sequence A does not produce one fast enough as a failsafe? So A gets a higher priority but if it doesn't yield a value in timeout time then a value from A is chosen? – Benjamin Gruenbaum Apr 12 '15 at 16:04
  • @Benjamin Gruenbaum: almost, but the other way around. B has the priority, A is the fallback. – Sammy S. Apr 12 '15 at 17:04
  • There's just not enough specification to warrant tackling this: it's not clear what values of a and b that x is dependent on; it's not clear how a producing subsequent values within the time-out period affects x. I think you are saying that a value from a starts a timeout, upon the expiry of which, or arrival of a b element the latest value of a and the possible b (where b could be no value) are fed into a result-selector to produce x? And at that point the next value of a starts a new timeout? What happens if there is a b and no a - does that b get fed into the result-selector immediately? – James World Apr 12 '15 at 19:56
  • And what about if there are multiple values of a within the timeout period? Will that produce a single output or one for each value of a? Does each value of a trigger a timeout or just the first value following an output event? – James World Apr 12 '15 at 22:36
  • 1
    Uh, I accidentially deleted my comment. It was: @JamesWorld: Sorry, I should have provided more information. Given that B produces a value, this value and the last value of A produce the output. But if the timeout occurs, I still need to produce output from A alone. This output is computed using a side-effect that depends on either the fact that A and B have a value or the value of A alone. In case only B delivers, that value is enough to So in essence your assumptions are correct. – Sammy S. Apr 12 '15 at 22:38
  • 1
    @JamesWorld: Every value of A resets the timeout until it can either be combined with a B value or produces a result without a B. It should behave like using `Sample()`. – Sammy S. Apr 12 '15 at 22:39

1 Answers1

1

I will take a stab at this. Given observables A and B then I think this will do the trick:

// 1500 millisecond timeout to be used on observable B.
TimeSpan timeout = TimeSpan.FromMilliseconds(1500);

var result =
    A
    .Select(a => 
        B
        .Timeout(timeout)
        .Materialize()
        .Take(1)
        .Select(b => b.Kind == NotificationKind.OnNext ? b.Value : a))
    .Switch();

The marble diagram for this should look like this:

                                               <-1500ms->Timeout
SeqA   |--------a0--------------a1-a2--------a3---------------------
SeqB   |b0--------b1----b2-----------b3-----------------------------
Output |----------b1-----------------b3------------------a3---------
Jason Boyd
  • 6,839
  • 4
  • 29
  • 47