// StartService starts the specified service. The operation parameter is used // for the context of the start; the service's URI, the referrer, signaling // completion of the service start, etc. // // Upon returning, either the operation has failed, or the service is still // going through the motions of being started. In the latter case, the caller // can wait for completion of the operation to ensure the service is fully // started. // func (h *ServiceHost) StartService(op *operation.Operation, s Service) { s.SetHost(h) // The selflink is expected to be either set on the service externally // (before starting the service), or as the URI path on the operation. selfLink := s.SelfLink() if selfLink == "" { // Prefix path with / to make sure it is absolute. // The clean function removes double /'s and the trailing /, if any. selfLink = path.Clean("/" + op.GetURI().Path) s.SetSelfLink(selfLink) } // Add service to the host's service map. h.Lock() _, ok := h.services[selfLink] if ok { h.Unlock() op.Fail(errors.New("host: service is already bound")) return } h.services[selfLink] = s h.Unlock() // Service is now attached to host; move to initialized state. if err := s.SetStage(StageInitialized); err != nil { op.Fail(err) return } // Start service asynchronously. go h.startService(op, s) }