Skip to content

Commit 8500ef9

Browse files
committed
BUG/MAJOR: runtime: fix race condition when calling runtime socket
Switched from using a channel and a goroutine to simple mutex, to avoid race condition when the goroutine is finished and a channel is being written to, making it block forever. Now a simple mutex is controlling the read/write to the runtime unix socket
1 parent 496b7ba commit 8500ef9

6 files changed

+38
-129
lines changed

runtime/acls_test.go

+6-20
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package runtime
22

33
import (
4-
"context"
54
"reflect"
65
"testing"
7-
"time"
86

97
"github.com/haproxytech/client-native/v6/models"
108
)
@@ -52,9 +50,7 @@ func TestSingleRuntime_ShowACLS(t *testing.T) {
5250
t.Run(tt.name, func(t *testing.T) {
5351
haProxy.SetResponses(&tt.socketResponse)
5452
s := &SingleRuntime{}
55-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
56-
defer cancel()
57-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
53+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
5854
if err != nil {
5955
t.Errorf("SingleRuntime.Init() error = %v", err)
6056
return
@@ -159,9 +155,7 @@ func TestSingleRuntime_GetACL(t *testing.T) {
159155
t.Run(tt.name, func(t *testing.T) {
160156
haProxy.SetResponses(&tt.socketResponse)
161157
s := &SingleRuntime{}
162-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
163-
defer cancel()
164-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
158+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
165159
if err != nil {
166160
t.Errorf("SingleRuntime.Init() error = %v", err)
167161
return
@@ -253,9 +247,7 @@ func TestSingleRuntime_ShowACLFileEntries(t *testing.T) {
253247
t.Run(tt.name, func(t *testing.T) {
254248
haProxy.SetResponses(&tt.socketResponse)
255249
s := &SingleRuntime{}
256-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
257-
defer cancel()
258-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
250+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
259251
if err != nil {
260252
t.Errorf("SingleRuntime.Init() error = %v", err)
261253
return
@@ -329,9 +321,7 @@ func TestSingleRuntime_GetACLFileEntry(t *testing.T) {
329321
t.Run(tt.name, func(t *testing.T) {
330322
haProxy.SetResponses(&tt.socketResponse)
331323
s := &SingleRuntime{}
332-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
333-
defer cancel()
334-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
324+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
335325
if err != nil {
336326
t.Errorf("SingleRuntime.Init() error = %v", err)
337327
return
@@ -436,9 +426,7 @@ func TestSingleRuntime_AddACLFileEntry(t *testing.T) {
436426
t.Run(tt.name, func(t *testing.T) {
437427
haProxy.SetResponses(&tt.socketResponse)
438428
s := &SingleRuntime{}
439-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
440-
defer cancel()
441-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
429+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
442430
if err != nil {
443431
t.Errorf("SingleRuntime.Init() error = %v", err)
444432
return
@@ -521,9 +509,7 @@ func TestSingleRuntime_DeleteACLFileEntry(t *testing.T) {
521509
t.Run(tt.name, func(t *testing.T) {
522510
haProxy.SetResponses(&tt.socketResponse)
523511
s := &SingleRuntime{}
524-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
525-
defer cancel()
526-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
512+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
527513
if err != nil {
528514
t.Errorf("SingleRuntime.Init() error = %v", err)
529515
return

runtime/certs_test.go

+8-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package runtime
22

33
import (
4-
"context"
54
"reflect"
65
"testing"
76
"time"
@@ -56,9 +55,7 @@ func TestSingleRuntime_ShowCerts(t *testing.T) {
5655
t.Run(tt.name, func(t *testing.T) {
5756
haProxy.SetResponses(&tt.socketResponse)
5857
s := &SingleRuntime{}
59-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
60-
defer cancel()
61-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
58+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
6259
if err != nil {
6360
t.Errorf("SingleRuntime.Init() error = %v", err)
6461
return
@@ -146,9 +143,7 @@ func TestSingleRuntime_GetCert(t *testing.T) {
146143
t.Run(tt.name, func(t *testing.T) {
147144
haProxy.SetResponses(&tt.socketResponse)
148145
s := &SingleRuntime{}
149-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
150-
defer cancel()
151-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
146+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
152147
if err != nil {
153148
t.Errorf("SingleRuntime.Init() error = %v", err)
154149
return
@@ -231,9 +226,7 @@ func TestSingleRuntime_ShowCertEntry(t *testing.T) {
231226
t.Run(tt.name, func(t *testing.T) {
232227
haProxy.SetResponses(&tt.socketResponse)
233228
s := &SingleRuntime{}
234-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
235-
defer cancel()
236-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
229+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
237230
if err != nil {
238231
t.Errorf("SingleRuntime.Init() error = %v", err)
239232
return
@@ -256,7 +249,6 @@ func TestSingleRuntime_NewCertEntry(t *testing.T) {
256249
defer haProxy.Stop()
257250

258251
type fields struct {
259-
jobs chan Task
260252
socketPath string
261253
masterWorkerMode bool
262254
}
@@ -308,9 +300,7 @@ func TestSingleRuntime_NewCertEntry(t *testing.T) {
308300
t.Run(tt.name, func(t *testing.T) {
309301
haProxy.SetResponses(&tt.socketResponse)
310302
s := &SingleRuntime{}
311-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
312-
defer cancel()
313-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
303+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
314304
if err != nil {
315305
t.Errorf("SingleRuntime.Init() error = %v", err)
316306
return
@@ -328,7 +318,6 @@ func TestSingleRuntime_SetCertEntry(t *testing.T) {
328318
defer haProxy.Stop()
329319

330320
type fields struct {
331-
jobs chan Task
332321
socketPath string
333322
masterWorkerMode bool
334323
}
@@ -396,9 +385,7 @@ func TestSingleRuntime_SetCertEntry(t *testing.T) {
396385
t.Run(tt.name, func(t *testing.T) {
397386
haProxy.SetResponses(&tt.socketResponse)
398387
s := &SingleRuntime{}
399-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
400-
defer cancel()
401-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
388+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
402389
if err != nil {
403390
t.Errorf("SingleRuntime.Init() error = %v", err)
404391
return
@@ -416,7 +403,6 @@ func TestSingleRuntime_CommitCertEntry(t *testing.T) {
416403
defer haProxy.Stop()
417404

418405
type fields struct {
419-
jobs chan Task
420406
socketPath string
421407
masterWorkerMode bool
422408
}
@@ -470,9 +456,7 @@ func TestSingleRuntime_CommitCertEntry(t *testing.T) {
470456
t.Run(tt.name, func(t *testing.T) {
471457
haProxy.SetResponses(&tt.socketResponse)
472458
s := &SingleRuntime{}
473-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
474-
defer cancel()
475-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
459+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
476460
if err != nil {
477461
t.Errorf("SingleRuntime.Init() error = %v", err)
478462
return
@@ -490,7 +474,6 @@ func TestSingleRuntime_AbortCertEntry(t *testing.T) {
490474
defer haProxy.Stop()
491475

492476
type fields struct {
493-
jobs chan Task
494477
socketPath string
495478
masterWorkerMode bool
496479
}
@@ -542,9 +525,7 @@ func TestSingleRuntime_AbortCertEntry(t *testing.T) {
542525
t.Run(tt.name, func(t *testing.T) {
543526
haProxy.SetResponses(&tt.socketResponse)
544527
s := &SingleRuntime{}
545-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
546-
defer cancel()
547-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
528+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
548529
if err != nil {
549530
t.Errorf("SingleRuntime.Init() error = %v", err)
550531
return
@@ -562,7 +543,6 @@ func TestSingleRuntime_DeleteCertEntry(t *testing.T) {
562543
defer haProxy.Stop()
563544

564545
type fields struct {
565-
jobs chan Task
566546
socketPath string
567547
masterWorkerMode bool
568548
}
@@ -614,9 +594,7 @@ func TestSingleRuntime_DeleteCertEntry(t *testing.T) {
614594
t.Run(tt.name, func(t *testing.T) {
615595
haProxy.SetResponses(&tt.socketResponse)
616596
s := &SingleRuntime{}
617-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
618-
defer cancel()
619-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
597+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
620598
if err != nil {
621599
t.Errorf("SingleRuntime.Init() error = %v", err)
622600
return

runtime/crt-lists_test.go

+5-20
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package runtime
22

33
import (
4-
"context"
54
"reflect"
65
"testing"
7-
"time"
86
)
97

108
func TestSingleRuntime_ShowCrtLists(t *testing.T) {
@@ -50,9 +48,7 @@ func TestSingleRuntime_ShowCrtLists(t *testing.T) {
5048
t.Run(tt.name, func(t *testing.T) {
5149
haProxy.SetResponses(&tt.socketResponse)
5250
s := &SingleRuntime{}
53-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
54-
defer cancel()
55-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
51+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
5652
if err != nil {
5753
t.Errorf("SingleRuntime.Init() error = %v", err)
5854
return
@@ -136,9 +132,7 @@ func TestSingleRuntime_GetCrtList(t *testing.T) {
136132
t.Run(tt.name, func(t *testing.T) {
137133
haProxy.SetResponses(&tt.socketResponse)
138134
s := &SingleRuntime{}
139-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
140-
defer cancel()
141-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
135+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
142136
if err != nil {
143137
t.Errorf("SingleRuntime.Init() error = %v", err)
144138
return
@@ -161,7 +155,6 @@ func TestSingleRuntime_ShowCrtListEntries(t *testing.T) {
161155
defer haProxy.Stop()
162156

163157
type fields struct {
164-
jobs chan Task
165158
socketPath string
166159
masterWorkerMode bool
167160
}
@@ -236,9 +229,7 @@ func TestSingleRuntime_ShowCrtListEntries(t *testing.T) {
236229
t.Run(tt.name, func(t *testing.T) {
237230
haProxy.SetResponses(&tt.socketResponse)
238231
s := &SingleRuntime{}
239-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
240-
defer cancel()
241-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
232+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
242233
if err != nil {
243234
t.Errorf("SingleRuntime.Init() error = %v", err)
244235
return
@@ -263,7 +254,6 @@ func TestSingleRuntime_AddCrtListEntry(t *testing.T) {
263254
defer haProxy.Stop()
264255

265256
type fields struct {
266-
jobs chan Task
267257
socketPath string
268258
masterWorkerMode bool
269259
}
@@ -338,9 +328,7 @@ func TestSingleRuntime_AddCrtListEntry(t *testing.T) {
338328
t.Run(tt.name, func(t *testing.T) {
339329
haProxy.SetResponses(&tt.socketResponse)
340330
s := &SingleRuntime{}
341-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
342-
defer cancel()
343-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
331+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
344332
if err != nil {
345333
t.Errorf("SingleRuntime.Init() error = %v", err)
346334
return
@@ -358,7 +346,6 @@ func TestSingleRuntime_DeleteCrtListEntry(t *testing.T) {
358346
defer haProxy.Stop()
359347

360348
type fields struct {
361-
jobs chan Task
362349
socketPath string
363350
masterWorkerMode bool
364351
}
@@ -407,9 +394,7 @@ func TestSingleRuntime_DeleteCrtListEntry(t *testing.T) {
407394
t.Run(tt.name, func(t *testing.T) {
408395
haProxy.SetResponses(&tt.socketResponse)
409396
s := &SingleRuntime{}
410-
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
411-
defer cancel()
412-
err := s.Init(ctx, tt.fields.socketPath, tt.fields.masterWorkerMode)
397+
err := s.Init(tt.fields.socketPath, tt.fields.masterWorkerMode)
413398
if err != nil {
414399
t.Errorf("SingleRuntime.Init() error = %v", err)
415400
return

runtime/interface.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ type Runtime interface {
149149
IsStatsSocket() bool
150150
}
151151

152-
func New(ctx context.Context, opt ...options.RuntimeOption) (Runtime, error) {
152+
func New(_ context.Context, opt ...options.RuntimeOption) (Runtime, error) {
153153
c := &client{
154154
options: options.RuntimeOptions{},
155155
}
@@ -163,9 +163,9 @@ func New(ctx context.Context, opt ...options.RuntimeOption) (Runtime, error) {
163163
}
164164

165165
if c.options.MasterSocketData != nil {
166-
err = c.initWithMasterSocket(ctx, c.options)
166+
err = c.initWithMasterSocket(c.options)
167167
} else {
168-
err = c.initWithSockets(ctx, c.options)
168+
err = c.initWithSockets(c.options)
169169
}
170170
if err != nil {
171171
return nil, err

runtime/runtime_client.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package runtime
1717

1818
import (
19-
"context"
2019
"errors"
2120
"fmt"
2221
"io"
@@ -36,7 +35,7 @@ import (
3635
type client struct {
3736
haproxyVersion *HAProxyVersion
3837
options options.RuntimeOptions
39-
runtime SingleRuntime
38+
runtime *SingleRuntime
4039
}
4140

4241
const (
@@ -47,12 +46,12 @@ const (
4746
maxBufSize = 8192
4847
)
4948

50-
func (c *client) initWithSockets(ctx context.Context, opt options.RuntimeOptions) error {
49+
func (c *client) initWithSockets(opt options.RuntimeOptions) error {
5150
socketPath := opt.Socket
5251

53-
runtime := SingleRuntime{}
52+
runtime := &SingleRuntime{}
5453
masterWorkerMode := false
55-
err := runtime.Init(ctx, socketPath, masterWorkerMode, opt)
54+
err := runtime.Init(socketPath, masterWorkerMode, opt)
5655
if err != nil {
5756
return err
5857
}
@@ -61,15 +60,15 @@ func (c *client) initWithSockets(ctx context.Context, opt options.RuntimeOptions
6160
return nil
6261
}
6362

64-
func (c *client) initWithMasterSocket(ctx context.Context, opt options.RuntimeOptions) error {
63+
func (c *client) initWithMasterSocket(opt options.RuntimeOptions) error {
6564
masterSocketPath := opt.MasterSocketData.MasterSocketPath
6665

6766
if masterSocketPath == "" {
6867
return errors.New("master socket not configured")
6968
}
70-
runtime := SingleRuntime{}
69+
runtime := &SingleRuntime{}
7170
masterWorkerMode := true
72-
err := runtime.Init(ctx, masterSocketPath, masterWorkerMode, opt)
71+
err := runtime.Init(masterSocketPath, masterWorkerMode, opt)
7372
if err != nil {
7473
return err
7574
}

0 commit comments

Comments
 (0)