He-Pin opened a new issue, #3211:
URL: https://github.com/apache/pekko/issues/3211

   ### Motivation
   
   `pekko.pattern.retry` 在 `maxAttempts` 耗尽后仍然多执行一次 `attempt` 调用,导致 
`attempts=N` 实际执行 `N+1` 次。这是一个 off-by-one 错误,影响所有使用 retry pattern 的用户。
   
   ### 当前代码行为
   
   `RetrySupport.scala` 中的 `retry` 方法:
   
   ```scala
   // RetrySupport.scala:382-396
   if (maxAttempts - attempted > 0) {
     val result = tryAttempt()
     if (result eq null)
       result
     else {
       result.transformWith {
         case Success(value) if shouldRetry(value, null)                        
=> doRetry(attempted + 1)
         case Failure(e) if NonFatal(e) && shouldRetry(null.asInstanceOf[T], e) 
=> doRetry(attempted + 1)
         case _                                                                 
=> result
       }
     }
   } else {
     tryAttempt()  // <-- 问题所在:maxAttempts 已耗尽仍执行
   }
   ```
   
   当 `maxAttempts - attempted <= 0` 时,`else` 分支仍然调用 `tryAttempt()`,这意味着:
   - `attempts=1` 会执行 2 次
   - `attempts=3` 会执行 4 次
   - `attempts=N` 会执行 `N+1` 次
   
   ### 预期行为
   
   当 `maxAttempts` 次尝试全部失败后,应该返回最后一次失败结果,而不是再执行一次。`else` 分支应该返回一个失败的 Future(例如 
`Future.failed(new IllegalStateException("maxAttempts reached"))`),或者去掉 else 
分支让初始调用包含在 attempts 计数中。
   
   ### 代码证据
   
   - `actor/src/main/scala/org/apache/pekko/pattern/RetrySupport.scala:382-396` 
— `if/else` 分支逻辑
   - `actor/src/main/scala/org/apache/pekko/pattern/RetrySupport.scala:363-375` 
— `doRetry` 每次递增 `attempted`
   
   ### 复现方式
   
   ```scala
   var count = 0
   val result = retry(
     attempt = () => { count += 1; Future.failed(new RuntimeException("fail")) 
},
     attempts = 3,
     minBackoff = 1.milli,
     maxBackoff = 1.milli,
     randomFactor = 0.0
   )(system.dispatcher, system.scheduler)
   // 预期: count == 3, 实际: count == 4
   ```
   
   ### 影响范围
   
   - 模块:`pekko-actor`,`pekko.pattern` 包
   - 影响所有使用 `retry` 工具方法的用户代码
   - 可能导致意外的额外副作用(如额外的网络请求、数据库查询)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to