Skip to content

manaswi-siripurapu/tenacity-cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tenacity

A tiny C++ library that retries your code when it fails.

This is the C++ version of the popular Python tenacity library. Intentionally named the same, so when you search for "tenacity cpp", "tenacity c++ version", or "retry library cpp", you land here and find something familiar that just works. The core idea is identical: wrap your unreliable code, tell it how many times to try and how long to wait, and let the library handle the rest.


What problem does this solve?

Sometimes code fails for no real reason - a network blip, a server that was briefly busy, a file that wasn't ready yet. If you just try again a moment later, it works fine.

Without tenacity, you'd write this by hand every time:

// the painful way, writing retry logic yourself
for (int i = 0; i < 3; i++) {
    try {
        connect_to_server();
        break;
    } catch (...) {
        if (i == 2) throw;
        sleep(1);
    }
}

With tenacity, the same thing looks like this:

// the easy way
tenacity::retry(3, []() {
    connect_to_server();
});

Same result. Much simpler.


Setup - 30 seconds

  1. Copy tenacity.hpp into your project folder
  2. Add this line at the top of your .cpp file:
    #include "tenacity.hpp"
  3. That's it. No installation, no build system, no dependencies.

How to use it

The simplest version, just retry

tenacity::Result r = tenacity::retry(3, []() {
    fetch_data_from_api();  // will be tried up to 3 times
});

if (r.success) {
    std::cout << "It worked!\n";
} else {
    std::cout << "Failed after " << r.attempts << " tries.\n";
    std::cout << "Last error: " << r.error << "\n";
}

Wait between attempts

// waits 2 seconds between each attempt
tenacity::retry_with_delay(4, 2.0, []() {
    fetch_data_from_api();
});

Wait longer each time (exponential backoff)

// waits 1s, then 2s, then 4s, then 8s...
// never waits more than 30s
tenacity::retry_with_backoff(5, []() {
    fetch_data_from_api();
}, 1.0, 30.0);

This is the smartest retry strategy. If a server is struggling, hammering it every second makes things worse. Waiting longer each time gives it room to recover.

Only retry certain errors

tenacity::retry_if(5, []() {
    fetch_data_from_api();
},
[](const std::string& error) {
    // retry timeouts (temporary), but not auth errors (permanent)
    return error.find("timeout") != std::string::npos;
});

If the error doesn't match, tenacity stops immediately instead of wasting attempts on something that will never work.


The Result struct

Every function returns a Result that tells you what happened:

tenacity::Result r = tenacity::retry(3, my_fn);

r.success    // true if it worked, false if all attempts failed
r.attempts   // how many times it tried (1, 2, 3...)
r.error      // the last error message if it failed

You can also just print it:

tenacity::print_result(r);
// prints: "Succeeded after 2 attempt(s)."
// or:     "Failed after 3 attempt(s). Last error: connection refused"

How it's built internally

The library is one file: tenacity.hpp. Here's the entire idea in plain English:

Each retry function is just a for-loop:

for attempt 1 to max_attempts:
    try running the function
    if it worked → return success
    if it failed → save the error, maybe wait, then loop again
return failure

That's genuinely it. No magic, no complex machinery.

The Result struct is just three variables bundled together - a bool, an int, and a string. It exists so you get back all the information from a retry in one neat package instead of scattered variables.

The sleep uses Sleep() on Windows and usleep() on Linux/Mac, wrapped behind a simple sleep_seconds() function so the rest of the code doesn't need to care about the platform difference.

The []() syntax (lambdas) is just a way to pass a chunk of code as an argument. When you write:

tenacity::retry(3, []() {
    do_something();
});

The []() { do_something(); } part is your function. tenacity calls it for you up to 3 times.


How to run demo and tests

Here's how to run on each OS:

g++ demo.cpp -o demo -std=c++17   //compile demo.cpp
./demo    //run demo
g++ tests.cpp -o tests -std=c++17   //compile tests.cpp
./tests     //run tests

When tests.cpp is executed, you should see 35 passed, 0 failed.

If you're on Windows, want to compile both the files at once and && gives you an error in PowerShell, just run the two lines separately, one at a time.


How is this different from other C++ retry libraries?

The entire library is contained in a single file - tenacity.hpp. There’s no installation, no build system, and no setup required. Just copy the file into your project and start using it. The implementation relies on plain, readable loops, so you don’t need advanced C++ knowledge to understand or modify it.

If you search for "tenacity cpp" or "retry library in cpp", this is a simple C++ equivalent of the Python Tenacity library. Designed with one core idea: simplicity over complexity.

This library makes a deliberate trade-off: it sacrifices some advanced features in favor of clarity, accessibility and it's easy to use nature.

This library Typical retry library
Lines of code ~120 500+
Files 1 10+
Build system needed No Usually yes
Templates used No Heavy
Beginner-friendly Yes Not really
Works without CMake Yes Usually no

The trade-off is that this library can't do some advanced things like returning values from the retried function, or composing strategies together. For learning, small scripts, and most real projects, it does everything you need and works out of the box, without unnecessary complexity.


Files in this project

tenacity.hpp   — the library itself (copy this into any project to use it)
main.cpp       — blank starting point for your own code
demo.cpp       — 8 demos walking through every feature with real scenarios
tests.cpp      — 35 tests covering every function and edge case
README.md      — this file
LICENSE        — MIT license (free to use for anything, personal or commercial)

If you found this useful, a ⭐ on GitHub goes a long way!

License

MIT - free to use in personal and commercial projects. See the LICENSE file for the legal text.

About

A simple C++ retry library, the C++ version of Python's tenacity.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages