func (h *ActualLRPLifecycleHandler) StartActualLRP(logger lager.Logger, w http.ResponseWriter, req *http.Request) { var err error logger = logger.Session("start-actual-lrp") request := &models.StartActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } before, after, err := h.db.StartActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey, request.ActualLrpNetInfo) if err != nil { response.Error = models.ConvertError(err) return } if before == nil { go h.actualHub.Emit(models.NewActualLRPCreatedEvent(after)) } else if !before.Equal(after) { go h.actualHub.Emit(models.NewActualLRPChangedEvent(before, after)) } }
func (h *DesiredLRPHandler) createUnclaimedActualLRPs(logger lager.Logger, keys []*models.ActualLRPKey) []int { count := len(keys) createdIndicesChan := make(chan int, count) works := make([]func(), count) logger = logger.Session("create-unclaimed-actual-lrp") for i, key := range keys { key := key works[i] = func() { logger.Info("starting", lager.Data{"actual_lrp_key": key}) actualLRPGroup, err := h.actualLRPDB.CreateUnclaimedActualLRP(logger, key) if err != nil { logger.Info("failed", lager.Data{"actual_lrp_key": key, "err_message": err.Error()}) } else { go h.actualHub.Emit(models.NewActualLRPCreatedEvent(actualLRPGroup)) createdIndicesChan <- int(key.Index) } } } throttlerSize := h.updateWorkersCount throttler, err := workpool.NewThrottler(throttlerSize, works) if err != nil { logger.Error("failed-constructing-throttler", err, lager.Data{"max_workers": throttlerSize, "num_works": len(works)}) return []int{} } go func() { throttler.Work() close(createdIndicesChan) }() createdIndices := make([]int, 0, count) for createdIndex := range createdIndicesChan { createdIndices = append(createdIndices, createdIndex) } return createdIndices }
}) Describe("Actual LRP Events", func() { var actualLRPGroup *models.ActualLRPGroup var actualLRP *models.ActualLRP BeforeEach(func() { actualLRP = models.NewUnclaimedActualLRP(models.NewActualLRPKey("some-guid", 0, "some-domain"), 1) actualLRPGroup = models.NewRunningActualLRPGroup(actualLRP) }) Context("when receiving a ActualLRPCreatedEvent", func() { var expectedEvent *models.ActualLRPCreatedEvent BeforeEach(func() { expectedEvent = models.NewActualLRPCreatedEvent(actualLRPGroup) payload, err := proto.Marshal(expectedEvent) Expect(err).NotTo(HaveOccurred()) payload = []byte(base64.StdEncoding.EncodeToString(payload)) fakeRawEventSource.NextReturns( sse.Event{ ID: "sup", Name: string(expectedEvent.EventType()), Data: payload, }, nil, ) }) It("returns the event", func() {
func (h *EvacuationHandler) EvacuateRunningActualLRP(logger lager.Logger, w http.ResponseWriter, req *http.Request) { logger = logger.Session("evacuate-running-actual-lrp") response := &models.EvacuationResponse{} response.KeepContainer = true defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) request := &models.EvacuateRunningActualLRPRequest{} err := parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } guid := request.ActualLrpKey.ProcessGuid index := request.ActualLrpKey.Index actualLRPGroup, err := h.actualLRPDB.ActualLRPGroupByProcessGuidAndIndex(logger, guid, index) if err != nil { if err == models.ErrResourceNotFound { response.KeepContainer = false return } logger.Error("failed-fetching-lrp-group", err) response.Error = models.ConvertError(err) return } instance := actualLRPGroup.Instance evacuating := actualLRPGroup.Evacuating // If the instance is not there, clean up the corresponding evacuating LRP, if one exists. if instance == nil { err = h.db.RemoveEvacuatingActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey) if err != nil { if err == models.ErrActualLRPCannotBeRemoved { logger.Debug("remove-evacuating-actual-lrp-failed") response.KeepContainer = false return } logger.Error("failed-removing-evacuating-actual-lrp", err) response.Error = models.ConvertError(err) return } go h.actualHub.Emit(models.NewActualLRPRemovedEvent(&models.ActualLRPGroup{Evacuating: evacuating})) response.KeepContainer = false return } if (instance.State == models.ActualLRPStateUnclaimed && instance.PlacementError == "") || (instance.State == models.ActualLRPStateClaimed && !instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey)) { if evacuating != nil && !evacuating.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey) { logger.Error("already-evacuated-by-different-cell", err) response.KeepContainer = false return } group, err := h.db.EvacuateActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey, request.ActualLrpNetInfo, request.Ttl) if err == models.ErrActualLRPCannotBeEvacuated { logger.Error("cannot-evacuate-actual-lrp", err) response.KeepContainer = false return } response.KeepContainer = true if err != nil { logger.Error("failed-evacuating-actual-lrp", err) response.Error = models.ConvertError(err) } else { go h.actualHub.Emit(models.NewActualLRPCreatedEvent(group)) } return } if (instance.State == models.ActualLRPStateUnclaimed && instance.PlacementError != "") || (instance.State == models.ActualLRPStateRunning && !instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey)) || instance.State == models.ActualLRPStateCrashed { response.KeepContainer = false err = h.db.RemoveEvacuatingActualLRP(logger, &evacuating.ActualLRPKey, &evacuating.ActualLRPInstanceKey) if err == nil { go h.actualHub.Emit(models.NewActualLRPRemovedEvent(&models.ActualLRPGroup{Evacuating: evacuating})) } if err != nil && err != models.ErrActualLRPCannotBeRemoved { response.KeepContainer = true response.Error = models.ConvertError(err) } return } if (instance.State == models.ActualLRPStateClaimed || instance.State == models.ActualLRPStateRunning) && instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey) { group, err := h.db.EvacuateActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey, request.ActualLrpNetInfo, request.Ttl) if err != nil { response.Error = models.ConvertError(err) return } go h.actualHub.Emit(models.NewActualLRPCreatedEvent(group)) err = h.unclaimAndRequestAuction(logger, request.ActualLrpKey) if err != nil { response.Error = models.ConvertError(err) return } } }