blob: 28cd6826e250e6ea9198347e38725d3f097da459 [file] [log] [blame]
khenaidoobf6e7bb2018-08-14 22:27:29 -04001/*
Joey Armstrong653504f2024-01-18 12:58:56 -05002* Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors
khenaidoobf6e7bb2018-08-14 22:27:29 -04003
Mahir Gunyel4b93c072023-07-21 11:55:08 +03004* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
khenaidoobf6e7bb2018-08-14 22:27:29 -04007
Mahir Gunyel4b93c072023-07-21 11:55:08 +03008* http://www.apache.org/licenses/LICENSE-2.0
khenaidoobf6e7bb2018-08-14 22:27:29 -04009
Mahir Gunyel4b93c072023-07-21 11:55:08 +030010* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
khenaidoobf6e7bb2018-08-14 22:27:29 -040015 */
khenaidoocfee5f42018-07-19 22:47:38 -040016package kvstore
17
serkant.uluderyac431f2c2021-02-24 17:32:43 +030018import (
yasin sapli5458a1c2021-06-14 22:24:38 +000019 "context"
serkant.uluderyac431f2c2021-02-24 17:32:43 +030020 "fmt"
yasin sapli5458a1c2021-06-14 22:24:38 +000021 "math"
22 "math/rand"
23 "time"
24)
25
26const (
27 minRetryInterval = 100
28 maxRetryInterval = 5000
29 incrementalFactor = 1.2
30 jitter = 0.2
serkant.uluderyac431f2c2021-02-24 17:32:43 +030031)
khenaidoocfee5f42018-07-19 22:47:38 -040032
33// ToString converts an interface value to a string. The interface should either be of
34// a string type or []byte. Otherwise, an error is returned.
35func ToString(value interface{}) (string, error) {
36 switch t := value.(type) {
37 case []byte:
38 return string(value.([]byte)), nil
39 case string:
40 return value.(string), nil
41 default:
42 return "", fmt.Errorf("unexpected-type-%T", t)
43 }
44}
45
46// ToByte converts an interface value to a []byte. The interface should either be of
47// a string type or []byte. Otherwise, an error is returned.
48func ToByte(value interface{}) ([]byte, error) {
49 switch t := value.(type) {
50 case []byte:
51 return value.([]byte), nil
52 case string:
53 return []byte(value.(string)), nil
54 default:
55 return nil, fmt.Errorf("unexpected-type-%T", t)
56 }
57}
serkant.uluderyac431f2c2021-02-24 17:32:43 +030058
yasin sapli5458a1c2021-06-14 22:24:38 +000059// backoff waits an amount of time that is proportional to the attempt value. The wait time in a range of
60// minRetryInterval and maxRetryInterval.
61func backoff(ctx context.Context, attempt int) error {
62 if attempt == 0 {
63 return nil
64 }
65 backoff := int(minRetryInterval + incrementalFactor*math.Exp(float64(attempt)))
66 backoff *= 1 + int(jitter*(rand.Float64()*2-1))
67 if backoff > maxRetryInterval {
68 backoff = maxRetryInterval
69 }
70 ticker := time.NewTicker(time.Duration(backoff) * time.Millisecond)
71 defer ticker.Stop()
72 select {
73 case <-ctx.Done():
74 return ctx.Err()
75 case <-ticker.C:
76 }
77 return nil
78}