registry.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright (C) 2015 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package nat
  7. import (
  8. "context"
  9. "sync"
  10. "time"
  11. )
  12. type DiscoverFunc func(ctx context.Context, renewal, timeout time.Duration) []Device
  13. var providers []DiscoverFunc
  14. func Register(provider DiscoverFunc) {
  15. providers = append(providers, provider)
  16. }
  17. func discoverAll(ctx context.Context, renewal, timeout time.Duration) map[string]Device {
  18. wg := &sync.WaitGroup{}
  19. wg.Add(len(providers))
  20. c := make(chan Device)
  21. done := make(chan struct{})
  22. for _, discoverFunc := range providers {
  23. go func(f DiscoverFunc) {
  24. defer wg.Done()
  25. for _, dev := range f(ctx, renewal, timeout) {
  26. select {
  27. case c <- dev:
  28. case <-ctx.Done():
  29. return
  30. }
  31. }
  32. }(discoverFunc)
  33. }
  34. nats := make(map[string]Device)
  35. go func() {
  36. defer close(done)
  37. for {
  38. select {
  39. case dev, ok := <-c:
  40. if !ok {
  41. return
  42. }
  43. nats[dev.ID()] = dev
  44. case <-ctx.Done():
  45. return
  46. }
  47. }
  48. }()
  49. wg.Wait()
  50. close(c)
  51. <-done
  52. return nats
  53. }