]> git.basschouten.com Git - openhab-addons.git/blob
5aa7065e34114f35883db36d15ca9300a153e776
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.energidataservice.internal.retry.strategy;
14
15 import java.time.Duration;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.energidataservice.internal.retry.RetryStrategy;
20
21 /**
22  * This implements a {@link RetryStrategy} for exponential backoff with jitter.
23  *
24  * @author Jacob Laursen - Initial contribution
25  */
26 @NonNullByDefault
27 public class ExponentialBackoff implements RetryStrategy {
28
29     private int attempts = 0;
30     private int factor = 2;
31     private double jitter = 0.0;
32     private Duration minimum = Duration.ofMillis(100);
33     private Duration maximum = Duration.ofHours(6);
34
35     public ExponentialBackoff() {
36     }
37
38     @Override
39     public Duration getDuration() {
40         long minimum = this.minimum.toMillis();
41         long maximum = this.maximum.toMillis();
42         long duration = minimum * (long) Math.pow(this.factor, this.attempts++);
43         if (jitter != 0.0) {
44             double rand = Math.random();
45             if ((((int) Math.floor(rand * 10)) & 1) == 0) {
46                 duration += (long) (rand * jitter * duration);
47             } else {
48                 duration -= (long) (rand * jitter * duration);
49             }
50         }
51         if (duration < minimum) {
52             duration = minimum;
53         }
54         if (duration > maximum) {
55             duration = maximum;
56         }
57         return Duration.ofMillis(duration);
58     }
59
60     public ExponentialBackoff withFactor(int factor) {
61         this.factor = factor;
62         return this;
63     }
64
65     public ExponentialBackoff withJitter(double jitter) {
66         this.jitter = jitter;
67         return this;
68     }
69
70     public ExponentialBackoff withMinimum(Duration minimum) {
71         this.minimum = minimum;
72         return this;
73     }
74
75     public ExponentialBackoff withMaximum(Duration maximum) {
76         this.maximum = maximum;
77         return this;
78     }
79
80     @Override
81     public boolean equals(@Nullable Object o) {
82         if (o == this) {
83             return true;
84         }
85         if (!(o instanceof ExponentialBackoff)) {
86             return false;
87         }
88         ExponentialBackoff other = (ExponentialBackoff) o;
89
90         return this.factor == other.factor && this.jitter == other.jitter && this.minimum.equals(other.minimum)
91                 && this.maximum.equals(other.maximum);
92     }
93
94     @Override
95     public final int hashCode() {
96         final int prime = 31;
97         int result = 1;
98         result = prime * result + factor;
99         result = prime * result + (int) jitter * 100;
100         result = prime * result + (int) minimum.toMillis();
101         result = prime * result + (int) maximum.toMillis();
102
103         return result;
104     }
105 }