func NewJobID() JobID { return JobID(guid.New()) }
// 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 } } }() }