From 8e050242674ad62c30cff3205d3b233842704368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Mar 2022 14:25:44 +0100 Subject: [PATCH] UPnP/SSDP: Worker, ping Manager URLs in parallel Ping all Manager URLs at once, and wait until they've all responded (or caused an error), instead of pinging them one by one sequentially. --- cmd/flamenco-worker/main.go | 57 ++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/cmd/flamenco-worker/main.go b/cmd/flamenco-worker/main.go index 4395b0c0..adaf7127 100644 --- a/cmd/flamenco-worker/main.go +++ b/cmd/flamenco-worker/main.go @@ -11,6 +11,7 @@ import ( "os" "os/signal" "runtime" + "sync" "syscall" "time" @@ -226,29 +227,53 @@ func autodiscoverManager(ctx context.Context) (string, error) { } // Try out the URLs to see which one responds. - // TODO: parallelise this. - usableURLs := make([]string, 0) + startTime := time.Now() + numUsableURLs := 0 + wg := new(sync.WaitGroup) + wg.Add(len(urls)) + mutex := new(sync.Mutex) + for idx, url := range urls { + go func(idx int, url string) { + defer wg.Done() + ok := pingManager(ctx, url) + + mutex.Lock() + defer mutex.Unlock() + + if ok { + numUsableURLs++ + } else { + // Erase the URL from the usable list. + urls[idx] = "" + } + }(idx, url) + } + wg.Wait() + log.Debug().Str("pingTime", time.Since(startTime).String()).Msg("pinging all Manager URLs done") + + if numUsableURLs == 0 { + return "", fmt.Errorf("autodetected %d URLs, but none were usable", len(urls)) + } + + // Find the first usable URL. + var firstURL string for _, url := range urls { - if pingManager(ctx, url) { - usableURLs = append(usableURLs, url) + if url != "" { + firstURL = url + break } } - switch len(usableURLs) { - case 0: - return "", fmt.Errorf("autodetected %d URLs, but none were usable", len(urls)) - - case 1: - log.Info().Str("url", usableURLs[0]).Msg("found Manager") - return usableURLs[0], nil - - default: + if numUsableURLs == 1 { + log.Info().Str("url", firstURL).Msg("found Manager") + } else { log.Info(). - Strs("urls", usableURLs). - Str("url", usableURLs[0]). + Strs("urls", urls). + Str("url", firstURL). Msg("found multiple usable URLs, using the first one") - return usableURLs[0], nil } + + return firstURL, nil } // pingManager connects to a Manager and returns true if it responds.