Algori...::LIMD(3pm)

πŸ“¦
version 0.010 Β· 5 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

🌸 NAME 🌸

Algorithm::Backoff::LIMD β€” Linear Increment, Multiplicative Decrement (LIMD) backoff πŸ’–

okay so real quick: this is the backoff module that goes up slowly when stuff breaks and drops fast when it works again. it's giving "gentle on the way up, dramatic on the way down" πŸ’…


✨ VERSION ✨

this doc is describing version 0.010 of Algorithm::Backoff::LIMD (from the Perl distribution Algorithm-Backoff), released on 2024-02-24 πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

use Algorithm::Backoff::LIMD;

# 1. instantiate

my $ab = Algorithm::Backoff::LIMD->new(
    #consider_actual_delay => 1, # optional, default 0
    #max_actual_duration   => 0, # optional, default 0 (retry endlessly)
    #max_attempts          => 0, # optional, default 0 (retry endlessly)
    #jitter_factor         => 0.25, # optional, default 0
    min_delay              => 1, # optional, default 0
    #max_delay             => 100, # optional
    initial_delay              => 2,   # required
    delay_increment_on_failure => 4,   # required
    delay_multiple_on_success  => 0.2, # required
);

# 2. log success/failure and get a new number of seconds to delay, timestamp is
# optional but must be monotonically increasing.

# for example, using the parameters initial_delay=2,
# delay_increment_on_failure=4, delay_multiple_on_success=0.2, min_delay=1:

my $secs;
$secs = $ab->failure();   # =>  2   (= initial_delay)
$secs = $ab->failure();   # =>  6   (2 + 4)
$secs = $ab->failure();   # => 10   (2 + 4)
$secs = $ab->success();   # =>  2   (10 * 0.2)
$secs = $ab->success();   # =>  1   (max(2 * 0.2, 1))
$secs = $ab->failure();   # =>  5   (1 + 4)

watch it in action with the CLI show-backoff-delays (3 failures, then 3 successes, then 3 failures again) πŸ’«

% show-backoff-delays -a LILD --initial-delay 2 --min-delay 1 \
    --delay-increment-on-failure 4 --delay-multiple-on-success 0.2 \
    0 0 0   1 1 1   0 0 0
2
6
10
2
1
1
5
9
13

πŸ‘‘ DESCRIPTION πŸ‘‘

when something fails, this backoff algorithm figures out the next delay like this:

D1 = initial_delay
D2 = min(D1 + delay_increment_on_failure, max_delay)
...

and when something succeeds, the next delay is:

D1 = initial_delay
D2 = max(D1 * delay_multiple_on_success, min_delay)
...

initial_delay, delay_increment_on_failure, and delay_multiple_on_success are required β€” no skipping, bestie, they're the whole personality of this algorithm 🫢

there are also limits on how many attempts you get (max_attempts) and how much total time you're allowed to burn (max_actual_duration).

highly recommend adding a jitter factor, like 0.25, to sprinkle in some randomness and dodge the "thundering herd problem" πŸ™ˆ nobody wants a stampede fr fr

πŸ’… METHODS πŸ’…

new

usage:

new(%args) -> obj

this function is not exported.

arguments (* means it's required, no take-backs):

  • consider_actual_delay => bool (default: 0) β€” whether to consider the actual delay.

if you set this to true, it takes the actual delay (the timestamp difference) into account. like, say you're using the Constant strategy with delay=2 and you log failure() again right after the previous failure() (same timestamp). then failure() returns ~2+2 = 4 seconds. but if you waited 2 seconds before calling failure() again (timestamp is 2 seconds bigger than before), failure() returns 2 seconds. and if you waited 4 seconds or more, failure() returns 0. ✨

  • delay_increment_on_failure* => float β€” how much to add to the previous delay, in seconds, when it fails (e.g. 5).
  • delay_multiple_on_success* => ufloat β€” how much to multiply the previous delay by, when it succeeds (e.g. 0.5).
  • initial_delay* => ufloat β€” the initial delay for the first attempt after failure, in seconds.
  • jitter_factor => float β€” how much randomness to add.

if you set this to a value larger than 0, the actual delay will be a random number between original_delay * (1-jitter_factor) and original_delay * (1+jitter_factor). jitters are usually added to avoid the so-called "thundering herd" problem.

the jitter gets applied to the delay on failure and on success. equal opportunity jitter πŸ’–

  • max_actual_duration => ufloat (default: 0) β€” maximum number of seconds for all of the attempts (0 means unlimited).

if set to a positive number, it limits the number of seconds across all the attempts. this setting is used to limit how much time you're willing to spend on a task. for example, with the Exponential strategy of initial_delay=3 and max_attempts=10, the delays would be 3, 6, 12, 24, .... if failures are logged according to the suggested delays and max_actual_duration is set to 21 seconds, then the third failure() returns -1 instead of 24, because 3+6+12 >= 21 β€” even though max_attempts hasn't been exceeded. it's giving "we're done here" πŸ›‘

  • max_attempts => uint (default: 0) β€” maximum number of consecutive failures before giving up.

0 means retry endlessly and never give up, main character energy. 1 means give up after a single failure (so, no retry attempts at all). 2 means retry once after a failure. note that after a success, the number of attempts gets reset (as expected, honestly). so if max_attempts is 3, and you fail twice then succeed, then on the next failure the algorithm will retry again for a maximum of 3 times. πŸ”

  • max_delay => ufloat β€” maximum delay time, in seconds.
  • min_delay => ufloat (default: 0) β€” maximum delay time, in seconds.

return value: (obj) 🌈


🧚 HOMEPAGE 🧚

please visit the project's homepage at <https://metacpan.org/release/Algorithm-Backoff>. ✨


πŸ“ SOURCE πŸ“

source repository is at <https://github.com/perlancar/perl-Algorithm-Backoff>. πŸ’œ


⭐ SEE ALSO ⭐

  • Algorithm::Backoff::LILD
  • Algorithm::Backoff::MILD
  • Algorithm::Backoff::MIMD
  • Algorithm::Backoff
  • other "Algorithm::Backoff::*" classes.

🌸 AUTHOR 🌸

perlancar <perlancar@cpan.org> πŸ‘‘


🫢 CONTRIBUTING 🫢

to contribute, you can send patches by email or via RT, or send pull requests on GitHub. no gatekeeping here πŸ’–

most of the time, you don't need to build the distribution yourself. you can just modify the code, then test via:

% prove -l

if you do want to build the distribution (like, to try installing it locally on your system), you can install Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, Pod::Weaver::PluginBundle::Author::PERLANCAR, and sometimes one or two other Dist::Zilla- and/or Pod::Weaver plugins. any additional steps required beyond that are considered a bug and can be reported to me. πŸ›


this software is copyright (c) 2024, 2019 by perlancar <perlancar@cpan.org>.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. slay πŸ’…


😭 BUGS 😭

please report any bugs or feature requests on the bugtracker website <https://rt.cpan.org/Public/Dist/Display.html?Name=Algorithm-Backoff>.

when submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. receipts, bestie πŸ“


okay that's the whole thing!! this was perl v5.40.1, dated 2025-05-04 β€” Algori...::LIMD(3pm) out, mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from