From 9c9c52cb2ec0f75f22e2a65ec9e76ebabbe4bab4 Mon Sep 17 00:00:00 2001 From: xigang Date: Wed, 8 Nov 2023 12:12:20 +0800 Subject: [PATCH] karmada-search: Fix lock race affects watch RestChan not close, causing client watch api to hang Signed-off-by: xigang --- pkg/search/proxy/store/util.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/search/proxy/store/util.go b/pkg/search/proxy/store/util.go index d8faad7a4..dbb765959 100644 --- a/pkg/search/proxy/store/util.go +++ b/pkg/search/proxy/store/util.go @@ -195,9 +195,21 @@ func (w *watchMux) AddSource(watcher watch.Interface, decorator func(watch.Event // Start run the watcher func (w *watchMux) Start() { - for _, source := range w.sources { - go w.startWatchSource(source.watcher, source.decorator) + wg := sync.WaitGroup{} + for i := range w.sources { + source := w.sources[i] + wg.Add(1) + go func() { + defer wg.Done() + w.startWatchSource(source.watcher, source.decorator) + }() } + + go func() { + // close result chan after all goroutines exit, avoiding data race. + defer close(w.result) + wg.Wait() + }() } // ResultChan implements watch.Interface @@ -220,7 +232,6 @@ func (w *watchMux) Stop() { case <-w.done: default: close(w.done) - close(w.result) } } @@ -246,19 +257,8 @@ func (w *watchMux) startWatchSource(source watch.Interface, decorator func(watch select { case <-w.done: return - default: + case w.result <- copyEvent: } - - func() { - w.lock.RLock() - defer w.lock.RUnlock() - select { - case <-w.done: - return - default: - w.result <- copyEvent - } - }() } }