Example #1
0
func NewJobID() JobID {
	return JobID(guid.New())
}
Example #2
0
// Subscribe registers a remote platform.Platform implementation as
// the daemon for an instance (identified by instID). Any
// platform.FatalError returned when processing requests will result
// in the platform being deregistered, with the error put on the
// channel `done`.
func (n *NATS) Subscribe(instID flux.InstanceID, remote platform.Platform, done chan<- error) {
	encoder := nats.EncoderForType(encoderType)

	requests := make(chan *nats.Msg)
	sub, err := n.raw.ChanSubscribe(string(instID)+".Platform.>", requests)
	if err != nil {
		done <- err
		return
	}

	// It's possible that more than one connection for a particular
	// instance will arrive at the service. To prevent confusion, when
	// a subscription arrives, it sends a "kick" message with a unique
	// ID (so it can recognise its own kick message). Any other
	// subscription for the instance _should_ then exit upon receipt
	// of the kick.
	myID := guid.New()
	n.raw.Publish(string(instID)+methodKick, []byte(myID))

	go func() {
		var err error
		for request := range requests {
			switch {
			case strings.HasSuffix(request.Subject, methodKick):
				id := string(request.Data)
				if id != myID {
					n.metrics.IncrKicks(instID)
					err = platform.FatalError{errors.New("Kicked by new subscriber " + id)}
				}
			case strings.HasSuffix(request.Subject, methodPing):
				var p ping
				err = encoder.Decode(request.Subject, request.Data, &p)
				if err == nil {
					err = remote.Ping()
				}
				n.enc.Publish(request.Reply, PingResponse{makeErrorResponse(err)})
			case strings.HasSuffix(request.Subject, methodAllServices):
				var (
					req fluxrpc.AllServicesRequest
					res []platform.Service
				)
				err = encoder.Decode(request.Subject, request.Data, &req)
				if err == nil {
					res, err = remote.AllServices(req.MaybeNamespace, req.Ignored)
				}
				n.enc.Publish(request.Reply, AllServicesResponse{res, makeErrorResponse(err)})
			case strings.HasSuffix(request.Subject, methodSomeServices):
				var (
					req []flux.ServiceID
					res []platform.Service
				)
				err = encoder.Decode(request.Subject, request.Data, &req)
				if err == nil {
					res, err = remote.SomeServices(req)
				}
				n.enc.Publish(request.Reply, SomeServicesResponse{res, makeErrorResponse(err)})
			case strings.HasSuffix(request.Subject, methodRegrade):
				var (
					req []platform.RegradeSpec
				)
				err = encoder.Decode(request.Subject, request.Data, &req)
				if err == nil {
					err = remote.Regrade(req)
				}
				response := RegradeResponse{}
				switch regradeErr := err.(type) {
				case platform.RegradeError:
					result := fluxrpc.RegradeResult{}
					for s, e := range regradeErr {
						result[s] = e.Error()
					}
					response.Result = result
				default:
					response.ErrorResponse = makeErrorResponse(err)
				}
				n.enc.Publish(request.Reply, response)
			default:
				err = errors.New("unknown message: " + request.Subject)
			}
			if _, ok := err.(platform.FatalError); ok && err != nil {
				sub.Unsubscribe()
				close(requests)
				done <- err
				return
			}
		}
	}()
}