Бесконечная последовательность запросов в Finagle с Future

У меня есть конечная точка HTTP API, которую мне нужно постоянно проверять на наличие новых значений. К счастью, он поддерживает длительный опрос. Итак, идея состоит в том, что мне нужно реализовать «бесконечный цикл», в котором я делаю запрос, жду ответа (максимум 10 минут), получаю какое-то значение из ответа и создаю побочный эффект, сохраняя их где-то, делаю еще один запрос.

Учитывая, что у меня есть функция, вызов которой запустит этот «бесконечный цикл», мне также нужно вернуть Closable, чтобы удовлетворить Finagle API, с которым я интегрируюсь, чтобы процесс можно было прервать. Если HTTP-запрос не работает, мне нужно немедленно повторить попытку.

Теперь мне нужно выяснить, как реализовать это с помощью Futures в Finagle. Интересно, могу ли я использовать рекурсию, применив преобразование к ответу Future? .. Или мне что-то не хватает, и есть более простой способ сделать это в Finagle?

Спасибо!


person Ashald    schedule 23.06.2016    source источник
comment
У меня была аналогичная проблема, но я решил ее с помощью http4s / scalaz-stream time.awakeEvery.map(<do http call>).   -  person Reactormonk    schedule 23.06.2016


Ответы (1)


Я не уверен, что могу представить, как это (то, что вы описали) можно сделать более простым, чем рекурсивный:

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

Обратите внимание, что на самом деле это не рекурсивно в традиционном смысле, поскольку обычно следует ожидать (с некоторыми оговорками) только один экземпляр keepCalling, который будет находиться в стеке в любой момент времени, поскольку "рекурсивный" вызов происходит в другом потоке.

person Dima    schedule 23.06.2016
comment
Спасибо! Значит ли это, что потребление памяти будет расти с каждым циклом? Или Scala позаботится об этом? Кроме того, как бы вы поступили с canceled? А var? Или есть лучший способ сделать это? - person Ashald; 23.06.2016
comment
Я не вижу в этом случае ничего, что предлагало бы вам беспокоиться о потреблении памяти больше, чем в любом другом приложении. Я имею в виду, вам действительно нужно беспокоиться об этом, и он будет расти, если вы не выпускаете ссылки должным образом, я просто не понимаю, почему этот случай должен заставить вас беспокоит больше, чем кто-либо другой. Что касается обработки cancelled ... да, наверное, var. В таком простом случае нет нужды в чем-то более изысканном. Только не забудьте сделать это volatile, чтобы обновления, сделанные в одном потоке, правильно увидели другой. - person Dima; 23.06.2016
comment
Супер спасибо! И последний вопрос: что, если makeRequest вернет неудачное будущее? «Петля» будет тормозить? Должны ли мы использовать что-то еще, а не flatMap, чтобы повторить попытку? - person Ashald; 23.06.2016
comment
Конечно. Вы можете вставить .rescue или .handle перед .flatMap для обработки исключений. - person Dima; 23.06.2016