Skip to content
This repository was archived by the owner on Sep 26, 2018. It is now read-only.

Commit 726472c

Browse files
committed
Add MaxConn field for the frontends config TOML
- This commit enables adding a MaxConn field on the frontends defined for Sidecar via the TOML specified in the Filename field. - Design discussed here: #7 (comment) and here: #8 (comment)
1 parent dbdbb90 commit 726472c

4 files changed

Lines changed: 107 additions & 30 deletions

File tree

configuration.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,6 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
336336
defaultSidecar.Endpoint = "http://127.0.0.1:7777"
337337
defaultSidecar.Filename = "sidecar.toml"
338338
defaultSidecar.RefreshConn = flaeg.Duration(60 * time.Second)
339-
defaultSidecar.MaxConns = 2000
340339

341340
//default Docker
342341
var defaultDocker provider.Docker

provider/sidecar.go

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import (
2323
)
2424

2525
const (
26-
method = "wrr"
27-
weight = 0
28-
sticky = false
29-
maxConnExtractorFunc = "request.host"
26+
method = "wrr"
27+
weight = 0
28+
sticky = false
29+
defaultMaxConnAmount = 2000
30+
defaultMaxConnExtractorFunc = "request.host"
3031
)
3132

3233
var (
@@ -51,7 +52,15 @@ type Sidecar struct {
5152
configurationChan chan<- types.ConfigMessage
5253
RefreshConn flaeg.Duration `description:"How often to refresh the connection to Sidecar backend"`
5354
connTimer *time.Timer
54-
MaxConns int64 `description:"Maximum number of connections allowed for each backend"`
55+
}
56+
57+
type sidecarFrontend struct {
58+
*types.Frontend
59+
MaxConn *types.MaxConn `json:"maxConn,omitempty"`
60+
}
61+
62+
type sidecarConfig struct {
63+
Frontends map[string]*sidecarFrontend `json:"frontends,omitempty"`
5564
}
5665

5766
type callback func(map[string][]*service.Service, error)
@@ -119,12 +128,32 @@ func (provider *Sidecar) Provide(configurationChan chan<- types.ConfigMessage, p
119128

120129
func (provider *Sidecar) constructConfig(sidecarStates *catalog.ServicesState) (*types.Configuration, error) {
121130
log.Infoln("loading sidecar config")
122-
sidecarConfig := types.Configuration{Backends: provider.makeBackends(sidecarStates)}
123-
var err error
124-
sidecarConfig.Frontends, err = provider.makeFrontends()
131+
sidecarConfig := types.Configuration{
132+
Backends: provider.makeBackends(sidecarStates),
133+
Frontends: map[string]*types.Frontend{},
134+
}
135+
136+
frontends, err := provider.makeFrontends()
125137
if err != nil {
126138
return nil, err
127139
}
140+
141+
for name, frontend := range frontends {
142+
sidecarConfig.Frontends[name] = frontend.Frontend
143+
144+
if backend, ok := sidecarConfig.Backends[name]; ok {
145+
backend.MaxConn = frontend.MaxConn
146+
147+
if backend.MaxConn == nil {
148+
backend.MaxConn = &types.MaxConn{
149+
Amount: defaultMaxConnAmount,
150+
ExtractorFunc: defaultMaxConnExtractorFunc,
151+
}
152+
}
153+
154+
}
155+
}
156+
128157
return &sidecarConfig, nil
129158
}
130159

@@ -203,12 +232,13 @@ func (provider *Sidecar) callbackLoader(sidecarStates *catalog.ServicesState, er
203232
provider.connTimer.Reset(time.Duration(provider.RefreshConn))
204233
}
205234

206-
func (provider *Sidecar) makeFrontends() (map[string]*types.Frontend, error) {
207-
configuration := new(types.Configuration)
235+
func (provider *Sidecar) makeFrontends() (map[string]*sidecarFrontend, error) {
236+
configuration := new(sidecarConfig)
208237
if _, err := toml.DecodeFile(provider.Filename, configuration); err != nil {
209238
log.Errorf("Error reading file: %s", err)
210239
return nil, err
211240
}
241+
212242
return configuration.Frontends, nil
213243
}
214244

@@ -223,10 +253,6 @@ func (provider *Sidecar) makeBackends(sidecarStates *catalog.ServicesState) map[
223253
backend = &types.Backend{
224254
LoadBalancer: &types.LoadBalancer{Method: method, Sticky: sticky},
225255
Servers: make(map[string]types.Server),
226-
MaxConn: &types.MaxConn{
227-
Amount: provider.MaxConns,
228-
ExtractorFunc: maxConnExtractorFunc,
229-
},
230256
}
231257

232258
sidecarBacks[svc.Name] = backend

provider/sidecar_test.go

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ func TestSidecar(t *testing.T) {
8585
Convey("create backends", func() {
8686
prov := Sidecar{
8787
Endpoint: "http://some.dummy.service",
88-
MaxConns: 10,
8988
}
9089

9190
dummyState.AddServiceEntry(
@@ -106,13 +105,58 @@ func TestSidecar(t *testing.T) {
106105
So(backs["web"].Servers["some-aws-host"].URL, ShouldEqual, "http://some-aws-host:8000")
107106
So(backs["api"].Servers["another-aws-host"], ShouldBeZeroValue)
108107

109-
So(backs["web"].MaxConn.Amount, ShouldEqual, 10)
110-
So(backs["web"].MaxConn.ExtractorFunc, ShouldEqual, "request.host")
111-
So(backs["api"].MaxConn.Amount, ShouldEqual, 10)
112-
So(backs["api"].MaxConn.ExtractorFunc, ShouldEqual, "request.host")
108+
So(backs["web"].MaxConn, ShouldBeNil)
109+
So(backs["api"].MaxConn, ShouldBeNil)
113110

114111
})
115112

113+
Convey("construct config", func() {
114+
prov := Sidecar{
115+
BaseProvider: BaseProvider{
116+
Filename: "testdata/sidecar_testdata.toml",
117+
},
118+
Endpoint: "http://some.dummy.service",
119+
}
120+
121+
dummyState.AddServiceEntry(
122+
service.Service{
123+
ID: "008",
124+
Name: "api",
125+
Hostname: "another-aws-host",
126+
Status: 1,
127+
},
128+
)
129+
130+
dummyState.AddServiceEntry(
131+
service.Service{
132+
ID: "009",
133+
Name: "sso",
134+
Hostname: "yet-another-aws-host",
135+
Status: 1,
136+
},
137+
)
138+
139+
states, err := prov.fetchState()
140+
So(err, ShouldBeNil)
141+
142+
config, err := prov.constructConfig(states)
143+
So(err, ShouldBeNil)
144+
145+
So(config.Frontends, ShouldContainKey, "web")
146+
So(config.Frontends, ShouldContainKey, "api")
147+
So(config.Frontends, ShouldNotContainKey, "sso")
148+
149+
So(config.Backends, ShouldContainKey, "web")
150+
So(config.Backends, ShouldContainKey, "api")
151+
So(config.Backends, ShouldContainKey, "sso")
152+
153+
So(config.Backends["web"].MaxConn.Amount, ShouldEqual, 10)
154+
So(config.Backends["web"].MaxConn.ExtractorFunc, ShouldEqual, "client.ip")
155+
So(config.Backends["api"].MaxConn.Amount, ShouldEqual, defaultMaxConnAmount)
156+
So(config.Backends["api"].MaxConn.ExtractorFunc, ShouldEqual, defaultMaxConnExtractorFunc)
157+
So(config.Backends["sso"].MaxConn, ShouldBeNil)
158+
})
159+
116160
Convey("run Provide", func() {
117161
prov := Sidecar{
118162
BaseProvider: BaseProvider{
@@ -196,8 +240,8 @@ func TestSidecar(t *testing.T) {
196240
},
197241
)
198242

199-
// Unblock the second call to recycleConn() to receive the updated config
200-
releaseWatch <- true
243+
// Unblock the rest of the calls to recycleConn() to receive the updated config
244+
close(releaseWatch)
201245
configMsg = <-configMsgChan
202246

203247
So(configMsg.Configuration.Backends, ShouldContainKey, "api")
@@ -224,11 +268,13 @@ func TestSidecarMakeFrontend(t *testing.T) {
224268
Endpoint: "http://some.dummy.service",
225269
}
226270

227-
conf, err := prov.makeFrontends()
271+
frontends, err := prov.makeFrontends()
228272
So(err, ShouldEqual, nil)
229-
So(conf["web"].PassHostHeader, ShouldEqual, true)
230-
So(conf["web"].EntryPoints, ShouldResemble, []string{"http", "https"})
231-
So(conf["web"].Routes["test_1"].Rule, ShouldEqual, "Host: some-aws-host")
273+
So(frontends, ShouldContainKey, "web")
274+
So(frontends, ShouldContainKey, "api")
275+
So(frontends["web"].PassHostHeader, ShouldEqual, true)
276+
So(frontends["web"].EntryPoints, ShouldResemble, []string{"http", "https"})
277+
So(frontends["web"].Routes["test_1"].Rule, ShouldEqual, "Host: some-aws-host")
232278

233279
prov.Filename = "testdata/dummyfile.toml"
234280
_, err = prov.makeFrontends()
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
[frontends]
22
[frontends.web]
3-
backend = "web"
4-
passHostHeader = true
5-
entrypoints = ["http","https"]
3+
backend = "web"
4+
passHostHeader = true
5+
entrypoints = ["http","https"]
66
[frontends.web.routes.test_1]
7-
rule = "Host: some-aws-host"
7+
rule = "Host: some-aws-host"
8+
[frontends.web.maxconn]
9+
amount = 10
10+
extractorfunc = "client.ip"
11+
[frontends.api]
12+
backend = "api"
13+
passHostHeader = true

0 commit comments

Comments
 (0)