From 7bb172798fbf90d8c5c5126b77f9ebf7c9d5361d 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 45e9fe281beb..9a5ce6833222 100644 --- a/pkg/search/proxy/store/util.go +++ b/pkg/search/proxy/store/util.go @@ -193,9 +193,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 @@ -218,7 +230,6 @@ func (w *watchMux) Stop() { case <-w.done: default: close(w.done) - close(w.result) } } @@ -244,19 +255,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 - } - }() } }