Skip to content

Commit 6c702ba

Browse files
sayborasjrajahalme
authored andcommitted
proxylib: Move proxylib from cilium to proxy repo
This is to make sure that we can build self-contained and independent proxy image, which will be used in cilium. Along with main implementation of proxylib, a minimal dependency is copied from cilium/cilium/pkg to cilium/proxy/pkg. Signed-off-by: Tam Mach <[email protected]>
1 parent 1b385a0 commit 6c702ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+10906
-94
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@
3939
/.clwb
4040

4141
/.vagrant
42+
43+
/proxylib/libcilium.so*
44+
/proxylib/_obj*

Makefile.defs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
include Makefile.quiet
1+
ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
2+
include $(ROOT_DIR)/Makefile.quiet
23

34
PREFIX?=/usr
45
BINDIR?=$(PREFIX)/bin

go.mod

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
module github.com/cilium/proxy
22

3-
go 1.13
3+
go 1.20
44

55
require (
66
github.com/census-instrumentation/opencensus-proto v0.3.0
7-
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1
7+
github.com/cilium/checkmate v1.0.3
8+
github.com/cilium/kafka v0.0.0-20180809090225-01ce283b732b
9+
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490
810
github.com/envoyproxy/protoc-gen-validate v0.6.2
911
github.com/golang/protobuf v1.5.2
10-
github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a
11-
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
12-
google.golang.org/grpc v1.43.0
13-
google.golang.org/protobuf v1.27.1
12+
github.com/google/uuid v1.3.0
13+
github.com/prometheus/client_model v0.3.0
14+
github.com/sasha-s/go-deadlock v0.3.1
15+
github.com/sirupsen/logrus v1.9.2
16+
github.com/stretchr/testify v1.8.1
17+
golang.org/x/sync v0.1.0
18+
golang.org/x/sys v0.5.0
19+
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e
20+
google.golang.org/grpc v1.51.0
21+
google.golang.org/protobuf v1.28.1
22+
k8s.io/klog/v2 v2.100.1
23+
)
24+
25+
require (
26+
github.com/davecgh/go-spew v1.1.1 // indirect
27+
github.com/go-logr/logr v1.2.3 // indirect
28+
github.com/golang/snappy v0.0.4 // indirect
29+
github.com/kr/pretty v0.3.1 // indirect
30+
github.com/kr/text v0.2.0 // indirect
31+
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
32+
github.com/pmezard/go-difflib v1.0.0 // indirect
33+
github.com/rogpeppe/go-internal v1.9.0 // indirect
34+
golang.org/x/net v0.7.0 // indirect
35+
golang.org/x/text v0.7.0 // indirect
36+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
37+
gopkg.in/yaml.v3 v3.0.1 // indirect
1438
)

go.sum

Lines changed: 63 additions & 72 deletions
Large diffs are not rendered by default.

pkg/backoff/backoff.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Authors of Cilium
3+
4+
package backoff
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"math"
10+
"time"
11+
12+
"github.com/google/uuid"
13+
"github.com/sirupsen/logrus"
14+
15+
"github.com/cilium/proxy/pkg/logging"
16+
"github.com/cilium/proxy/pkg/logging/logfields"
17+
"github.com/cilium/proxy/pkg/rand"
18+
)
19+
20+
var (
21+
log = logging.DefaultLogger.WithField(logfields.LogSubsys, "backoff")
22+
23+
randGen = rand.NewSafeRand(time.Now().UnixNano())
24+
)
25+
26+
// Exponential implements an exponential backoff
27+
type Exponential struct {
28+
// Min is the minimal backoff time, if unspecified, 1 second will be
29+
// used
30+
Min time.Duration
31+
32+
// Max is the maximum backoff time, if unspecified, no maximum time is
33+
// applied
34+
Max time.Duration
35+
36+
// Factor is the factor the backoff time grows exponentially, if
37+
// unspecified, a factor of 2.0 will be used
38+
Factor float64
39+
40+
// Jitter, when enabled, adds random jitter to the interval
41+
Jitter bool
42+
43+
// Name is a free form string describing the operation subject to the
44+
// backoff, if unspecified, a UUID is generated. This string is used
45+
// for logging purposes.
46+
Name string
47+
48+
// ResetAfter will reset the exponential back-off if no attempt is made for the amount of time specified here.
49+
// Needs to be larger than the Max duration, otherwise it will be ignored to avoid accidental resets.
50+
// If unspecified, no reset is performed.
51+
ResetAfter time.Duration
52+
53+
lastBackoffStart time.Time
54+
55+
attempt int
56+
}
57+
58+
// CalculateDuration calculates the backoff duration based on minimum base
59+
// interval, exponential factor, jitter and number of failures.
60+
func CalculateDuration(min, max time.Duration, factor float64, jitter bool, failures int) time.Duration {
61+
minFloat := float64(min)
62+
maxFloat := float64(max)
63+
64+
t := minFloat * math.Pow(factor, float64(failures))
65+
if max != time.Duration(0) && t > maxFloat {
66+
t = maxFloat
67+
}
68+
69+
if jitter {
70+
t = randGen.Float64()*(t-minFloat) + minFloat
71+
}
72+
73+
return time.Duration(t)
74+
}
75+
76+
// ClusterSizeDependantInterval returns a time.Duration that is dependent on
77+
// the cluster size, i.e. the number of nodes that have been discovered. This
78+
// can be used to control sync intervals of shared or centralized resources to
79+
// avoid overloading these resources as the cluster grows.
80+
//
81+
// Example sync interval with baseInterval = 1 * time.Minute
82+
//
83+
// nodes | sync interval
84+
// ------+-----------------
85+
// 1 | 41.588830833s
86+
// 2 | 1m05.916737320s
87+
// 4 | 1m36.566274746s
88+
// 8 | 2m11.833474640s
89+
// 16 | 2m49.992800643s
90+
// 32 | 3m29.790453687s
91+
// 64 | 4m10.463236193s
92+
// 128 | 4m51.588744261s
93+
// 256 | 5m32.944565093s
94+
// 512 | 6m14.416550710s
95+
// 1024 | 6m55.946873494s
96+
// 2048 | 7m37.506428894s
97+
// 4096 | 8m19.080616652s
98+
// 8192 | 9m00.662124608s
99+
// 16384 | 9m42.247293667s
100+
func ClusterSizeDependantInterval(baseInterval time.Duration, numNodes int) time.Duration {
101+
// no nodes are being managed, no work will be performed, return
102+
// baseInterval to check again in a reasonable timeframe
103+
if numNodes == 0 {
104+
return baseInterval
105+
}
106+
107+
waitNanoseconds := float64(baseInterval.Nanoseconds()) * math.Log1p(float64(numNodes))
108+
return time.Duration(int64(waitNanoseconds))
109+
}
110+
111+
// Reset backoff attempt counter
112+
func (b *Exponential) Reset() {
113+
b.attempt = 0
114+
}
115+
116+
// Wait waits for the required time using an exponential backoff
117+
func (b *Exponential) Wait(ctx context.Context) error {
118+
if resetDuration := b.ResetAfter; resetDuration != time.Duration(0) && resetDuration > b.Max {
119+
if !b.lastBackoffStart.IsZero() {
120+
if time.Since(b.lastBackoffStart) > resetDuration {
121+
b.Reset()
122+
}
123+
}
124+
}
125+
126+
b.lastBackoffStart = time.Now()
127+
b.attempt++
128+
t := b.Duration(b.attempt)
129+
130+
log.WithFields(logrus.Fields{
131+
"time": t,
132+
"attempt": b.attempt,
133+
"name": b.Name,
134+
}).Debug("Sleeping with exponential backoff")
135+
136+
select {
137+
case <-ctx.Done():
138+
return fmt.Errorf("exponential backoff cancelled via context: %s", ctx.Err())
139+
case <-time.After(t):
140+
}
141+
142+
return nil
143+
}
144+
145+
// Duration returns the wait duration for the nth attempt
146+
func (b *Exponential) Duration(attempt int) time.Duration {
147+
if b.Name == "" {
148+
b.Name = uuid.New().String()
149+
}
150+
151+
min := time.Duration(1) * time.Second
152+
if b.Min != time.Duration(0) {
153+
min = b.Min
154+
}
155+
156+
factor := float64(2)
157+
if b.Factor != float64(0) {
158+
factor = b.Factor
159+
}
160+
161+
t := CalculateDuration(min, b.Max, factor, b.Jitter, attempt)
162+
163+
if b.Max != time.Duration(0) && t > b.Max {
164+
t = b.Max
165+
}
166+
167+
return t
168+
}

pkg/backoff/backoff_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Authors of Cilium
3+
4+
package backoff
5+
6+
import (
7+
"fmt"
8+
"math"
9+
"testing"
10+
"time"
11+
12+
check "github.com/cilium/checkmate"
13+
)
14+
15+
func Test(t *testing.T) {
16+
check.TestingT(t)
17+
}
18+
19+
type BackoffSuite struct{}
20+
21+
var _ = check.Suite(&BackoffSuite{})
22+
23+
func (b *BackoffSuite) TestJitter(c *check.C) {
24+
var prev time.Duration
25+
for i := 0; i < 100; i++ {
26+
current := CalculateDuration(time.Second, time.Minute, 2.0, true, 1)
27+
c.Assert(current, check.Not(check.Equals), prev)
28+
prev = current
29+
}
30+
}
31+
32+
type fakeNodeManager struct {
33+
nodes *int
34+
}
35+
36+
func (f *fakeNodeManager) ClusterSizeDependantInterval(baseInterval time.Duration) time.Duration {
37+
numNodes := *f.nodes
38+
39+
if numNodes == 0 {
40+
return baseInterval
41+
}
42+
43+
waitNanoseconds := float64(baseInterval.Nanoseconds()) * math.Log1p(float64(numNodes))
44+
return time.Duration(int64(waitNanoseconds))
45+
}
46+
47+
func (b *BackoffSuite) TestJitterDistribution(c *check.C) {
48+
nodeBackoff := &Exponential{
49+
Min: time.Second,
50+
Factor: 2.0,
51+
}
52+
53+
for attempt := 1; attempt <= 8; attempt++ {
54+
current := nodeBackoff.Duration(attempt).Round(time.Second / 10)
55+
fmt.Printf("%d: %s\n", attempt, current)
56+
}
57+
}

pkg/flowdebug/flowdebug.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Authors of Cilium
3+
4+
package flowdebug
5+
6+
import (
7+
"github.com/sirupsen/logrus"
8+
)
9+
10+
var perFlowDebug = false
11+
12+
// Enable enables per-flow debugging
13+
func Enable() {
14+
perFlowDebug = true
15+
}
16+
17+
// Enabled reports the status of per-flow debugging
18+
func Enabled() bool {
19+
return perFlowDebug
20+
}
21+
22+
// Log must be used to log any debug messages emitted per request/message/connection
23+
func Log(l *logrus.Entry, args ...interface{}) {
24+
if perFlowDebug {
25+
l.Debug(args...)
26+
}
27+
}
28+
29+
// Logf must be used to log any debug messages emitted per request/message/connection
30+
func Logf(l *logrus.Entry, format string, args ...interface{}) {
31+
if perFlowDebug {
32+
l.Debugf(format, args...)
33+
}
34+
}

0 commit comments

Comments
 (0)