mateclaw/mateclaw-server/src/main/java/vip/mate/channel/ExponentialBackoff.java
matevip 579d60125b Initial commit: MateClaw — Java + Vue 3 AI Assistant System
Full-stack AI assistant built on Spring AI Alibaba.
Features: ReAct Agent, Plan-and-Execute, MCP Protocol, Multi-Model, Multi-Channel.

Apache-2.0 License
2026-04-04 19:03:49 +08:00

85 lines
2.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package vip.mate.channel;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 指数退避工具类
* <p>
* 用于断线重连、Token 刷新失败重试等场景。
* 每次调用 {@link #nextDelayMs()} 返回递增的延迟时间(带上限),
* 重连成功后调用 {@link #reset()} 重置计数器。
*
* @author MateClaw Team
*/
public class ExponentialBackoff {
private final long initialDelayMs;
private final long maxDelayMs;
private final double factor;
private final int maxAttempts;
private final AtomicInteger attempts = new AtomicInteger(0);
/**
* @param initialDelayMs 初始延迟(毫秒)
* @param maxDelayMs 最大延迟上限(毫秒)
* @param factor 退避倍数(通常为 2.0
* @param maxAttempts 最大重试次数(-1 表示无限重试)
*/
public ExponentialBackoff(long initialDelayMs, long maxDelayMs, double factor, int maxAttempts) {
this.initialDelayMs = initialDelayMs;
this.maxDelayMs = maxDelayMs;
this.factor = factor;
this.maxAttempts = maxAttempts;
}
/** 默认配置2s 起步30s 上限2 倍递增,无限重试 */
public ExponentialBackoff() {
this(2000, 30000, 2.0, -1);
}
/**
* 计算下一次延迟(毫秒),并递增尝试次数
*
* @return 延迟毫秒数
*/
public long nextDelayMs() {
int attempt = attempts.getAndIncrement();
long delay = (long) (initialDelayMs * Math.pow(factor, attempt));
return Math.min(delay, maxDelayMs);
}
/**
* 是否已超过最大重试次数
*/
public boolean isExhausted() {
if (maxAttempts < 0) return false;
return attempts.get() >= maxAttempts;
}
/**
* 重置退避计数器(重连成功后调用)
*/
public void reset() {
attempts.set(0);
}
/**
* 当前已尝试次数
*/
public int getAttempts() {
return attempts.get();
}
public int getMaxAttempts() {
return maxAttempts;
}
public long getInitialDelayMs() {
return initialDelayMs;
}
public long getMaxDelayMs() {
return maxDelayMs;
}
}