Boost Massive Task Retries with Fast‑Retry: A High‑Performance Async Framework

This article introduces Fast‑Retry, a high‑performance asynchronous multi‑task retry framework for Java, compares its speed against Spring‑Retry and Guava‑Retry, and provides step‑by‑step code examples for dependency setup, task creation, annotation usage, and custom retry annotations.

macrozheng
macrozheng
macrozheng
Boost Massive Task Retries with Fast‑Retry: A High‑Performance Async Framework

Introduction

When you need to poll and retry identity information for millions of users, traditional single‑task synchronous retry frameworks such as Spring‑Retry or Guava‑Retry become impractical, even with many machines or threads. Fast‑Retry is designed specifically for this massive‑scale scenario.

Fast‑Retry Overview

Fast‑Retry is a high‑performance multi‑task retry framework that supports asynchronous retries for millions of tasks, offers both programmatic and annotation‑based usage, and allows custom result‑based retry logic.

Performance Comparison

The following table shows the execution time for different task counts when using Fast‑Retry, Spring‑Retry, and Guava‑Retry. Fast‑Retry consistently completes in around 10 seconds even for 1 million tasks, while the other frameworks take orders of magnitude longer.

Task Count

FastRetry

Spring‑Retry

Guava‑Retry

1

10 s

10 s

10 s

10

10.066 s

20.092 s

20.078 s

50

10.061 s

70.186 s

70.168 s

100

10.077 s

130.33 s

130.31 s

500

10.154 s

631.420 s

631.53 s

1 000

10.237 s

1254.78 s

1256.28 s

5 000

10.482 s

≈6 250 s

≈6 250 s

10 000

10.686 s

≈12 520 s

≈12 520 s

100 000

13.71 s

≈125 000 s

≈125 000 s

500 000

28.89 s

≈625 000 s

≈625 000 s

1 000 000

58.05 s

≈1 250 000 s

≈1 250 000 s

Quick Start

Dependency

<dependency>
    <groupId>io.github.burukeyou</groupId>
    <artifactId>fast-retry-all</artifactId>
    <version>0.2.0</version>
</dependency>

Building Retry Tasks

There are three main ways to construct retry tasks. For simple usage, prefer FastRetryBuilder or the @FastRetry annotation.

Using RetryQueue Directly

ExecutorService executorService = Executors.newFixedThreadPool(8);
RetryQueue queue = new FastRetryQueue(executorService);
RetryTask<String> task = new RetryTask<String>() {
    int result = 0;
    // Interval before next retry
    @Override
    public long waitRetryTime() { return 2000; }
    // Retry logic
    @Override
    public boolean retry() { return ++result < 5; }
    // Result after retries
    @Override
    public String getResult() { return result + ""; }
};
CompletableFuture<String> future = queue.submit(task);
log.info("Task finished, result:{}", future.get());

Using FastRetryBuilder

RetryResultPolicy<String> resultPolicy = result -> result.equals("444");
FastRetryer<String> retryer = FastRetryBuilder.<String>builder()
        .attemptMaxTimes(3)
        .waitRetryTime(3, TimeUnit.SECONDS)
        .retryIfException(true)
        .retryIfExceptionOfType(TimeoutException.class)
        .exceptionRecover(true)
        .resultPolicy(resultPolicy)
        .build();
CompletableFuture<String> future = retryer.submit(() -> {
    log.info("retry");
    if (0 < 10) {
        throw new TimeoutException("test");
    }
    return "444";
});
String o = future.get();
log.info("Result {}", o);

Using @FastRetry Annotation

@FastRetry(retryWait = @RetryWait(delay = 2))
public String retryTask() {
    return "success";
}

@FastRetry(retryWait = @RetryWait(delay = 2))
public CompletableFuture<String> retryTaskAsync() {
    return CompletableFuture.completedFuture("success");
}

Custom Retry Annotation

If the built‑in annotation does not meet your needs, you can define your own annotation, mark it with @FastRetry, specify a custom AnnotationRetryTaskFactory, and implement the task‑building logic. The default implementation is FastRetryAnnotationRetryTaskFactory.

Usage Recommendations

Regardless of the construction method, it is recommended to use asynchronous retry (returning CompletableFuture) and handle the result with whenComplete for non‑blocking execution.

Comparison Case Study

A weather‑service retry task was executed for 1 000 cities. Using Spring‑Retry took about 1 256 seconds, while Fast‑Retry completed in roughly 10 seconds, demonstrating the dramatic performance advantage of asynchronous multi‑task retry.

// Fast‑Retry weather service
@FastRetry(maxAttempts = 100, retryWait = @RetryWait(delay = 2, timeUnit = TimeUnit.SECONDS))
public CompletableFuture<WeatherResult> getFutureWeatherForCompare(String cityName) {
    log.info("Fast‑Retry attempt {} for city {}", ++index, cityName);
    WeatherResult weather = WeatherServer.getWeather(cityName);
    if (weather == null) {
        throw new RuntimeException("simulate exception for retry");
    }
    return FastRetryBuilder.of(weather);
}

// Spring‑Retry equivalent
@Retryable(maxAttempts = 100, backoff = @Backoff(delay = 2000))
public WeatherResult getSpringWeatherForCompare(String cityName) {
    log.info("Spring‑Retry attempt {} for city {}", ++index, cityName);
    WeatherResult weather = WeatherServer.getWeather(cityName);
    if (weather == null) {
        throw new RuntimeException("simulate exception for retry");
    }
    return weather;
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaperformancespringfast-retryasynchronous-retry
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.