Skip to content

Commit 725288a

Browse files
authored
Merge pull request #385 from apelisse/add-racy-update-spec
Make sure updating spec is not racy
2 parents 7562a10 + 6d87595 commit 725288a

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

Diff for: pkg/handler/handler.go

-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"fmt"
2323
"net/http"
2424
"strconv"
25-
"sync"
2625
"time"
2726

2827
"github.com/NYTimes/gziphandler"
@@ -127,9 +126,6 @@ func RegisterOpenAPIVersionedService(spec *spec.Swagger, servePath string, handl
127126

128127
// RegisterOpenAPIVersionedService registers a handler to provide access to provided swagger spec.
129128
func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handler common.PathHandler) {
130-
// Mutex protects the cache chain
131-
var mutex sync.Mutex
132-
133129
accepted := []struct {
134130
Type string
135131
SubType string
@@ -158,9 +154,7 @@ func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handl
158154
continue
159155
}
160156
// serve the first matching media type in the sorted clause list
161-
mutex.Lock()
162157
result := accepts.GetDataAndEtag.Get()
163-
mutex.Unlock()
164158
if result.Err != nil {
165159
klog.Errorf("Error in OpenAPI handler: %s", result.Err)
166160
// only return a 503 if we have no older cache data to serve

Diff for: pkg/handler/handler_test.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -227,23 +227,31 @@ func TestConcurrentReadStaleCache(t *testing.T) {
227227
t.Errorf("Unexpected error in preparing returnedPb: %v", err)
228228
}
229229

230-
jsonResults := make(chan []byte)
231-
protoResults := make(chan []byte)
230+
jsonResultsChan := make(chan []byte)
231+
protoResultsChan := make(chan []byte)
232+
updateSpecChan := make(chan struct{})
232233
for i := 0; i < concurrency; i++ {
233-
go func() { jsonResults <- getJSONBodyOrDie(server) }()
234-
go func() { protoResults <- getProtoBodyOrDie(server) }()
234+
go func() {
235+
sc := s
236+
o.UpdateSpec(&sc)
237+
updateSpecChan <- struct{}{}
238+
}()
239+
go func() { jsonResultsChan <- getJSONBodyOrDie(server) }()
240+
go func() { protoResultsChan <- getProtoBodyOrDie(server) }()
235241
}
236242
for i := 0; i < concurrency; i++ {
237-
r := <-jsonResults
243+
r := <-jsonResultsChan
238244
if !reflect.DeepEqual(r, returnedJSON) {
239245
t.Errorf("Returned and expected JSON do not match: got %v, want %v", string(r), string(returnedJSON))
240246
}
241247
}
242248
for i := 0; i < concurrency; i++ {
243-
r := <-protoResults
249+
r := <-protoResultsChan
244250
if !reflect.DeepEqual(r, returnedPb) {
245251
t.Errorf("Returned and expected pb do not match: got %v, want %v", r, returnedPb)
246252
}
247253
}
248-
254+
for i := 0; i < concurrency; i++ {
255+
<-updateSpecChan
256+
}
249257
}

0 commit comments

Comments
 (0)