0

I have an HTTP API endpoint that I need constantly check for new values. Luckily, it's supports long polling. So the idea is that I need to implement 'an infinite loop' where I do a request, wait for a response (at most 10mins), get some value from response and produce a side-effect by storing them somewhere, make another request.

Given that I have some function the call to which will start this 'infinite loop' I also need to return a Closable to satisfy Finagle API I'm integrating with so the process can be interrupted. If HTTP request fails I need to re-try immediately.

Now I need to figure out how to implement this with Futures in Finagle. I wonder whether I can user a recursion by applying transform to response Future?.. Or am I missing something and there is a more straightforward way to do it in Finagle?

Thanks!

Ashald
  • 72
  • 1
  • 8

1 Answers1

2

I am not sure I can imagine how it (what you described) can be made any more straightforward than recursive:

  def keepCalling: Future[Unit] = makeRequest
    .flatMap { response => 
       processResponse(response)
       if(cancelled) Future.Unit else keepCalling
     }

Note, that this is actually not recursive in the traditional sense, as we should normally expect (with some reservations) only one instance of keepCalling to be on stack at any given time, since the "recursive" invocation happens on a different thread.

Dima
  • 39,570
  • 6
  • 44
  • 70
  • Thanks! So, does it mean that memory consumption will grow with each cycle? Or Scala will take care of that? Also, how would you handle `canceled`? A `var`? Or there some better way to do that? – Ashald Jun 23 '16 at 16:14
  • I don't see anything about this case that suggests you should worry about memory consumption any more than in any other application. I mean, you _do_ need to worry about it, and it _will_ grow if you are not releasing the refs properly, I just don't see why this case should make you any more worried than any other. As for handling `cancelled` ... yeah, a `var`, I guess. No need for anything fancier in a simple case like this. Just be sure to make it `volatile`, so that updates made in one thread are properly seen by the other. – Dima Jun 23 '16 at 16:23
  • Super thanks! And the last question what if `makeRequest ` will return a failing future? The 'loop' will brake? Should we use something else rather then `flatMap` to have a 'retry'? – Ashald Jun 23 '16 at 16:43
  • sure. You can can a `.rescue` or `.handle` inserted before `.flatMap` to handle the exceptions. – Dima Jun 23 '16 at 17:04
  • I ended up doing something like this: https://gist.github.com/Ashald/87684ccd50ed66d6ce3b27b4f68fb61b (sorry I wasn't able to put that snippet properly into the comment) Does it look reasonable? Thanks! – Ashald Jun 23 '16 at 17:37