Повторная попытка моно, кажется, создает бесконечный цикл - PullRequest
1 голос
/ 17 января 2020

Я пытаюсь изучить Reactor, и я создал следующий пример:

  fun dbThingErrorSometimes() : Mono<String> {
        return if (Random.nextBoolean()){
            processDbResult(pooledClient.execute("SELECT * FROM product"))
        }else{
            Mono.error(RuntimeException("boom"))
        }
    }

тогда, где он используется, я делаю (в контроллере):

 @RequestMapping("/dbpooledretry")
    @ResponseBody
    fun dbExamplePoolRetrying(): Mono<String> {
        return dbService.dbThingErrorSometimes()
                .retry()
    }

, когда он приходит с ошибкой он застревает в бесконечном l oop (вызов rest никогда не возвращается и процессор уходит на 100%). Почему?

Ответы [ 2 ]

4 голосов
/ 18 января 2020

Ваш метод retry() просто повторяет попытку издателя, возвращаемого dbService.dbThingErrorSometimes(), который может быть Mono.error(). dbService.dbThingErrorSometimes() никогда не вызывается повторно, издатель, которого он издает, просто переподписывается.

Так что, если он выдает , выдает ошибку, то повторная подписка на эту же ошибку издателя не когда-либо изменится результат, следовательно, ваш бесконечный l oop.

Вместо этого вы, вероятно, захотите сделать Mono ленивым, повторно вызывая dbService.dbThingErrorSometimes() каждый раз, когда вы повторите попытку - вы можете достичь этого, завершение вызова этого метода в Mono.defer().

0 голосов
/ 17 января 2020

Как указано в документации Mono # retry

Повторно подписывается на эту последовательность Mono, если она сигнализирует о любой ошибке, неопределенно .

Так что, как и предполагалось, он будет повторяться до конца нашей жизни.

...