class FailoverHaStrategy<T> extends AbstractHaStrategy<T> {

    protected ThreadLocal<List<Referer<T>>> referersHolder = ThreadLocal.withInitial(ArrayList::new);

    @Override
    public Response call(Request request, LoadBalance<T> loadBalance) {
        if (loadBalance.canSelectMulti()) {
            return callWithMultiReferer(request, loadBalance);
        } else {
            return callWithSingleReferer(request, loadBalance);
        }
    }

    protected Response callWithSingleReferer(Request request, LoadBalance<T> loadBalance) {
        int tryCount = getTryCount(request);
        for (int i = 0; i <= tryCount; i++) {
            Referer<T> referer = loadBalance.select(request);
            if (referer == null) {
                throw new MotanServiceException(String.format("FailoverHaStrategy No referers for request:%s, load balance:%s", request,
                        loadBalance));
            }
            try {
                request.setRetries(i);
                return referer.call(request);
            } catch (RuntimeException e) {
                // For business exceptions, throw them directly
                if (ExceptionUtil.isBizException(e)) {
                    throw e;
                } else if (i >= tryCount) {
                    throw e;
                }
                LoggerUtil.warn(String.format("FailoverHaStrategy Call false for request:%s error=%s", request, e.getMessage()));
            }
        }
        throw new MotanFrameworkException("FailoverHaStrategy.call should not come here!");
    }

    // select multi referers at one time
    protected Response callWithMultiReferer(Request request, LoadBalance<T> loadBalance) {
        List<Referer<T>> referers = selectReferers(request, loadBalance);
        if (referers.isEmpty()) {
            throw new MotanServiceException(String.format("FailoverHaStrategy No referers for request:%s, loadbalance:%s", request,
                    loadBalance));
        }
        int tryCount = getTryCount(request);
        for (int i = 0; i <= tryCount; i++) {
            Referer<T> refer = referers.get(i % referers.size());
            try {
                request.setRetries(i);
                return refer.call(request);
            } catch (RuntimeException e) {
                // For business exceptions, throw them directly
                if (ExceptionUtil.isBizException(e)) {
                    throw e;
                } else if (i >= tryCount) {
                    throw e;
                }
                LoggerUtil.warn(String.format("FailoverHaStrategy Call false for request:%s error=%s", request, e.getMessage()));
            }
        }
        throw new MotanFrameworkException("FailoverHaStrategy.call should not come here!");
    }

    protected int getTryCount(Request request) {<FILL_FUNCTION_BODY>}

    protected List<Referer<T>> selectReferers(Request request, LoadBalance<T> loadBalance) {
        List<Referer<T>> referers = referersHolder.get();
        referers.clear();
        loadBalance.selectToHolder(request, referers);
        return referers;
    }

}

        int tryCount =
                url.getMethodParameter(request.getMethodName(), request.getParamtersDesc(), URLParamType.retries.getName(),
                        URLParamType.retries.getIntValue());
        // If it is a negative number, not retry
        if (tryCount < 0) {
            tryCount = 0;
        }
        return tryCount;
    
<methods>public non-sealed void <init>() ,public void setUrl(com.weibo.api.motan.rpc.URL) <variables>protected com.weibo.api.motan.rpc.URL url