1

The problem is to emulate the double looping behavior with RX:

while True:
    try:
        token = get_token()
        while True:
            try:
                value = get_value_using_token(token)
                do_something(value)
            except:
                break
    except:
        break

It would be clean if the two loops are replaced with two observables, one acting as an observer of the outer one, while do_something(value) can be replaced with an observer on its own. Any exceptions can be handled nicely as well. Outer loop needs to be blocking, but inner loop may not be, as I am trying to use outer loop to handle exceptions using retry function with a backoff function.

So far I can build a sequence using:

Observable.from_iterable(value for value in iter(get_token, None))
    .subscribe(do_something)

but how can I make a similar structure in blocking mode for the outer?

Jaewan Kim
  • 45
  • 5

2 Answers2

1

You just need to use the Repeat operator to create a loop. And then you need the Retry operator to continue on failure.

Something like

Observable.return(get_token())
    .flatMap(token->Observable.return(get_value_using_token(token))
        .repeat())
    .retry()
.subscribe(do_something)

*I dont know python, so I hope you can convert that psuedo code

Lee Campbell
  • 10,631
  • 1
  • 34
  • 29
  • Thanks. But repeat operator returns the same value. What I need is to repeat function invocation, as neither `get_token` nor `get_value_using_token` is a pure function. – Jaewan Kim Apr 07 '16 at 15:55
  • Sorry, of course. Then you can change Observable.Return to RxPy's equivilent of `Observable.Start` or you can use `Observable.Defer(Obs.Return(GetToken()))` this will make it lazily evalualted again. – Lee Campbell Apr 08 '16 at 01:09
0

What I ended up doing was to create an infinite stream of functions using repeat operator, and map to its invocation.

def get_token():
    return some_value

def get_value_with_token(token):
    return some_value_using_token

Observable.repeat(get_token)\
    .map(lambda f: f())\
    .map(lambda n: O.repeat(lambda: get_value_with_token(n)))\
    .concat_all()\
    .map(lambda f: f())\
    .subscribe(logger.info)

where get_token and get_value_with_token are functions.

By using blocking functions for both, I can make a double loop, and apply additional rx operators such as retry to the observable.

Jaewan Kim
  • 45
  • 5