Example #1
0
// 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)
}