Skip to content

Commit 1054b75

Browse files
author
Thibault Gilles
committed
Perfom less reload when servers change
1 parent 1cecb04 commit 1054b75

File tree

3 files changed

+244
-126
lines changed

3 files changed

+244
-126
lines changed

haproxy/dataplane.go

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,29 @@ type dataplaneClient struct {
3030
type tnx struct {
3131
txID string
3232
client *dataplaneClient
33+
34+
after []func() error
3335
}
3436

35-
func (c *dataplaneClient) Tnx() (*tnx, error) {
37+
func (c *dataplaneClient) Tnx() *tnx {
38+
return &tnx{
39+
client: c,
40+
}
41+
}
42+
43+
func (t *tnx) ensureTnx() error {
44+
if t.txID != "" {
45+
return nil
46+
}
3647
res := models.Transaction{}
37-
err := c.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/transactions?version=%d", c.version), nil, &res)
48+
err := t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/transactions?version=%d", t.client.version), nil, &res)
3849
if err != nil {
39-
return nil, err
50+
return err
4051
}
4152

42-
return &tnx{
43-
txID: res.ID,
44-
client: c,
45-
}, nil
53+
t.txID = res.ID
54+
55+
return nil
4656
}
4757

4858
func (c *dataplaneClient) Info() (*models.ProcessInfo, error) {
@@ -64,57 +74,113 @@ func (c *dataplaneClient) Stats() (models.NativeStats, error) {
6474
}
6575

6676
func (t *tnx) Commit() error {
67-
err := t.client.makeReq(http.MethodPut, fmt.Sprintf("/v1/services/haproxy/transactions/%s", t.txID), nil, nil)
68-
if err != nil {
69-
return err
77+
if t.txID != "" {
78+
err := t.client.makeReq(http.MethodPut, fmt.Sprintf("/v1/services/haproxy/transactions/%s", t.txID), nil, nil)
79+
if err != nil {
80+
return err
81+
}
82+
83+
t.client.version++
7084
}
7185

72-
t.client.version++
86+
for _, f := range t.after {
87+
err := f()
88+
if err != nil {
89+
return err
90+
}
91+
}
7392

7493
return nil
7594
}
7695

96+
func (t *tnx) After(fn func() error) {
97+
t.after = append(t.after, fn)
98+
}
99+
77100
func (t *tnx) CreateFrontend(fe models.Frontend) error {
101+
if err := t.ensureTnx(); err != nil {
102+
return err
103+
}
78104
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/frontends?transaction_id=%s", t.txID), fe, nil)
79105
}
80106

81107
func (t *tnx) DeleteFrontend(name string) error {
108+
if err := t.ensureTnx(); err != nil {
109+
return err
110+
}
82111
return t.client.makeReq(http.MethodDelete, fmt.Sprintf("/v1/services/haproxy/configuration/frontends/%s?transaction_id=%s", name, t.txID), nil, nil)
83112
}
84113

85114
func (t *tnx) CreateBind(feName string, bind models.Bind) error {
115+
if err := t.ensureTnx(); err != nil {
116+
return err
117+
}
86118
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/binds?frontend=%s&transaction_id=%s", feName, t.txID), bind, nil)
87119
}
88120

89121
func (t *tnx) DeleteBackend(name string) error {
122+
if err := t.ensureTnx(); err != nil {
123+
return err
124+
}
90125
return t.client.makeReq(http.MethodDelete, fmt.Sprintf("/v1/services/haproxy/configuration/backends/%s?transaction_id=%s", name, t.txID), nil, nil)
91126
}
92127

93128
func (t *tnx) CreateBackend(be models.Backend) error {
129+
if err := t.ensureTnx(); err != nil {
130+
return err
131+
}
94132
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/backends?transaction_id=%s", t.txID), be, nil)
95133
}
96134

97135
func (t *tnx) CreateServer(beName string, srv models.Server) error {
136+
if err := t.ensureTnx(); err != nil {
137+
return err
138+
}
98139
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/servers?backend=%s&transaction_id=%s", beName, t.txID), srv, nil)
99140
}
100141

101142
func (t *tnx) ReplaceServer(beName string, srv models.Server) error {
143+
if err := t.ensureTnx(); err != nil {
144+
return err
145+
}
102146
return t.client.makeReq(http.MethodPut, fmt.Sprintf("/v1/services/haproxy/configuration/servers/%s?backend=%s&transaction_id=%s", srv.Name, beName, t.txID), srv, nil)
103147
}
104148

149+
func (c *dataplaneClient) ReplaceServer(beName string, srv models.Server) error {
150+
err := c.makeReq(http.MethodPut, fmt.Sprintf("/v1/services/haproxy/configuration/servers/%s?backend=%s&version=%d", srv.Name, beName, c.version), srv, nil)
151+
if err != nil {
152+
return err
153+
}
154+
155+
c.version++
156+
return nil
157+
}
158+
105159
func (t *tnx) DeleteServer(beName string, name string) error {
160+
if err := t.ensureTnx(); err != nil {
161+
return err
162+
}
106163
return t.client.makeReq(http.MethodDelete, fmt.Sprintf("/v1/services/haproxy/configuration/servers/%s?backend=%s&transaction_id=%s", name, beName, t.txID), nil, nil)
107164
}
108165

109166
func (t *tnx) CreateFilter(parentType, parentName string, filter models.Filter) error {
167+
if err := t.ensureTnx(); err != nil {
168+
return err
169+
}
110170
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/filters?parent_type=%s&parent_name=%s&transaction_id=%s", parentType, parentName, t.txID), filter, nil)
111171
}
112172

113173
func (t *tnx) CreateTCPRequestRule(parentType, parentName string, rule models.TCPRequestRule) error {
174+
if err := t.ensureTnx(); err != nil {
175+
return err
176+
}
114177
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/tcp_request_rules?parent_type=%s&parent_name=%s&transaction_id=%s", parentType, parentName, t.txID), rule, nil)
115178
}
116179

117180
func (t *tnx) CreateLogTargets(parentType, parentName string, rule models.LogTarget) error {
181+
if err := t.ensureTnx(); err != nil {
182+
return err
183+
}
118184
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/log_targets?parent_type=%s&parent_name=%s&transaction_id=%s", parentType, parentName, t.txID), rule, nil)
119185
}
120186

haproxy/haproxy.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ type HAProxy struct {
2727
cfgC chan consul.Config
2828
currentCfg *consul.Config
2929

30+
upstreamServerSlots map[string][]upstreamSlot
31+
3032
haConfig *haConfig
3133
}
3234

3335
func New(consulClient *api.Client, cfg chan consul.Config, opts Options) *HAProxy {
3436
return &HAProxy{
35-
opts: opts,
36-
consulClient: consulClient,
37-
cfgC: cfg,
37+
opts: opts,
38+
consulClient: consulClient,
39+
cfgC: cfg,
40+
upstreamServerSlots: make(map[string][]upstreamSlot),
3841
}
3942
}
4043

@@ -107,13 +110,10 @@ func (h *HAProxy) Run(sd *lib.Shutdown) error {
107110
}
108111

109112
func (h *HAProxy) init() error {
110-
tx, err := h.dataplaneClient.Tnx()
111-
if err != nil {
112-
return err
113-
}
113+
tx := h.dataplaneClient.Tnx()
114114

115115
timeout := int64(30000)
116-
err = tx.CreateBackend(models.Backend{
116+
err := tx.CreateBackend(models.Backend{
117117
Name: "spoe_back",
118118
ServerTimeout: &timeout,
119119
ConnectTimeout: &timeout,
@@ -137,12 +137,9 @@ func (h *HAProxy) init() error {
137137
}
138138

139139
func (h *HAProxy) handleChange(cfg consul.Config) error {
140-
tx, err := h.dataplaneClient.Tnx()
141-
if err != nil {
142-
return err
143-
}
140+
tx := h.dataplaneClient.Tnx()
144141

145-
err = h.handleDownstream(tx, cfg.Downstream)
142+
err := h.handleDownstream(tx, cfg.Downstream)
146143
if err != nil {
147144
return err
148145
}

0 commit comments

Comments
 (0)