gopkg.in/docker/libcompose.v0@v0.4.0/project/service-wrapper.go (about) 1 package project 2 3 import ( 4 "sync" 5 6 log "github.com/Sirupsen/logrus" 7 "github.com/docker/libcompose/project/events" 8 ) 9 10 type serviceWrapper struct { 11 name string 12 service Service 13 done sync.WaitGroup 14 state ServiceState 15 err error 16 project *Project 17 noWait bool 18 ignored map[string]bool 19 } 20 21 func newServiceWrapper(name string, p *Project) (*serviceWrapper, error) { 22 wrapper := &serviceWrapper{ 23 name: name, 24 state: StateUnknown, 25 project: p, 26 ignored: map[string]bool{}, 27 } 28 29 return wrapper, wrapper.Reset() 30 } 31 32 func (s *serviceWrapper) IgnoreDep(name string) { 33 s.ignored[name] = true 34 } 35 36 func (s *serviceWrapper) Reset() error { 37 if s.state != StateExecuted { 38 service, err := s.project.CreateService(s.name) 39 if err != nil { 40 log.Errorf("Failed to create service for %s : %v", s.name, err) 41 return err 42 } 43 44 s.service = service 45 } 46 47 if s.err == ErrRestart { 48 s.err = nil 49 } 50 s.done.Add(1) 51 52 return nil 53 } 54 55 func (s *serviceWrapper) Ignore() { 56 defer s.done.Done() 57 58 s.state = StateExecuted 59 s.project.Notify(events.ServiceUpIgnored, s.service.Name(), nil) 60 } 61 62 func (s *serviceWrapper) waitForDeps(wrappers map[string]*serviceWrapper) bool { 63 if s.noWait { 64 return true 65 } 66 67 for _, dep := range s.service.DependentServices() { 68 if s.ignored[dep.Target] { 69 continue 70 } 71 72 if wrapper, ok := wrappers[dep.Target]; ok { 73 if wrapper.Wait() == ErrRestart { 74 s.project.Notify(events.ProjectReload, wrapper.service.Name(), nil) 75 s.err = ErrRestart 76 return false 77 } 78 } else { 79 log.Errorf("Failed to find %s", dep.Target) 80 } 81 } 82 83 return true 84 } 85 86 func (s *serviceWrapper) Do(wrappers map[string]*serviceWrapper, start, done events.EventType, action func(service Service) error) { 87 defer s.done.Done() 88 89 if s.state == StateExecuted { 90 return 91 } 92 93 if wrappers != nil && !s.waitForDeps(wrappers) { 94 return 95 } 96 97 s.state = StateExecuted 98 99 s.project.Notify(start, s.service.Name(), nil) 100 101 s.err = action(s.service) 102 if s.err == ErrRestart { 103 s.project.Notify(done, s.service.Name(), nil) 104 s.project.Notify(events.ProjectReloadTrigger, s.service.Name(), nil) 105 } else if s.err != nil { 106 log.Errorf("Failed %s %s : %v", start, s.name, s.err) 107 } else { 108 s.project.Notify(done, s.service.Name(), nil) 109 } 110 } 111 112 func (s *serviceWrapper) Wait() error { 113 s.done.Wait() 114 return s.err 115 }