manager.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package backend
  2. import (
  3. "fmt"
  4. "strings"
  5. "sync"
  6. log "github.com/coreos/flannel/Godeps/_workspace/src/github.com/golang/glog"
  7. "github.com/coreos/flannel/Godeps/_workspace/src/golang.org/x/net/context"
  8. "github.com/coreos/flannel/subnet"
  9. )
  10. var backendCtors map[string]BackendCtor = make(map[string]BackendCtor)
  11. type Manager interface {
  12. GetBackend(backendType string) (Backend, error)
  13. Wait()
  14. }
  15. type manager struct {
  16. ctx context.Context
  17. sm subnet.Manager
  18. extIface *ExternalInterface
  19. mux sync.Mutex
  20. active map[string]Backend
  21. wg sync.WaitGroup
  22. }
  23. func NewManager(ctx context.Context, sm subnet.Manager, extIface *ExternalInterface) Manager {
  24. return &manager{
  25. ctx: ctx,
  26. sm: sm,
  27. extIface: extIface,
  28. }
  29. }
  30. func (bm *manager) GetBackend(backendType string) (Backend, error) {
  31. bm.mux.Lock()
  32. defer bm.mux.Unlock()
  33. betype := strings.ToLower(backendType)
  34. // see if one is already running
  35. if be, ok := bm.active[betype]; ok {
  36. return be, nil
  37. }
  38. // first request, need to create and run it
  39. befunc, ok := backendCtors[betype]
  40. if !ok {
  41. return nil, fmt.Errorf("unknown backend type: %v", betype)
  42. }
  43. be, err := befunc(bm.sm, bm.extIface)
  44. if err != nil {
  45. return nil, err
  46. }
  47. bm.wg.Add(1)
  48. go func() {
  49. be.Run(bm.ctx)
  50. // TODO(eyakubovich): this obviosly introduces a race.
  51. // GetBackend() could get called while we are here.
  52. // Currently though, all backends' Run exit only
  53. // on shutdown
  54. bm.mux.Lock()
  55. delete(bm.active, betype)
  56. bm.mux.Unlock()
  57. bm.wg.Done()
  58. }()
  59. return be, nil
  60. }
  61. func (bm *manager) Wait() {
  62. bm.wg.Wait()
  63. }
  64. func Register(name string, ctor BackendCtor) {
  65. log.Infof("Register: %v", name)
  66. backendCtors[name] = ctor
  67. }