// State currently does not return tasks or lrp rootfs, because the // auctioneer currently does not need them. func (a *AuctionCellRep) State() (rep.CellState, error) { logger := a.logger.Session("auction-state") logger.Info("providing") totalResources, err := a.fetchResourcesVia(a.client.TotalResources) if err != nil { logger.Error("failed-to-get-total-resources", err) return rep.CellState{}, err } availableResources, err := a.fetchResourcesVia(a.client.RemainingResources) if err != nil { logger.Error("failed-to-get-remaining-resource", err) return rep.CellState{}, err } containers, err := a.client.ListContainers(nil) if err != nil { logger.Error("failed-to-fetch-containers", err) return rep.CellState{}, err } var taskGuid, taskDomain string var key *models.ActualLRPKey var keyErr error tasks := []rep.Task{} lrps := []rep.LRP{} for i := range containers { container := &containers[i] resource := rep.Resource{MemoryMB: int32(container.MemoryMB), DiskMB: int32(container.DiskMB)} if container.Tags[rep.LifecycleTag] == rep.TaskLifecycle { taskGuid, taskDomain, keyErr = taskKeyFromTags(container.Tags) if keyErr != nil { logger.Error("failed-to-extract-task key", keyErr) continue } tasks = append(tasks, rep.NewTask(taskGuid, taskDomain, resource)) } else { key, keyErr = rep.ActualLRPKeyFromTags(container.Tags) if keyErr != nil { logger.Error("failed-to-extract-key", keyErr) continue } lrps = append(lrps, rep.NewLRP(*key, resource)) } } state := rep.NewCellState(a.rootFSProviders, availableResources, totalResources, lrps, tasks, a.zone, a.evacuationReporter.Evacuating()) a.logger.Info("provided", lager.Data{ "available-resources": state.AvailableResources, "total-resources": state.TotalResources, "num-lrps": len(state.LRPs), "zone": state.Zone, "evacuating": state.Evacuating, }) return state, nil }
func BuildLRPAuctions(start auctioneer.LRPStartRequest, queueTime time.Time) []auctiontypes.LRPAuction { auctions := make([]auctiontypes.LRPAuction, 0, len(start.Indices)) for _, index := range start.Indices { lrpKey := models.NewActualLRPKey(start.ProcessGuid, int32(index), start.Domain) auctions = append(auctions, auctiontypes.NewLRPAuction(rep.NewLRP(lrpKey, start.Resource), queueTime)) } return auctions }
func (a *AuctionRunner) ScheduleLRPsForAuctions(lrpStarts []auctioneer.LRPStartRequest) { a.lock.Lock() defer a.lock.Unlock() now := a.clock.Now() for _, start := range lrpStarts { log.Infof("+lrp auction posted: %v: %v\n", start.ProcessGuid, start.Indices) for _, i := range start.Indices { lrpKey := models.NewActualLRPKey(start.ProcessGuid, int32(i), start.Domain) auction := auctiontypes.NewLRPAuction(rep.NewLRP(lrpKey, start.Resource), now) a.lrpAuctions = append(a.lrpAuctions, auction) } } a.claimToHaveWork() }
func (b *Batch) AddLRPStarts(starts []auctioneer.LRPStartRequest) { auctions := make([]auctiontypes.LRPAuction, 0, len(starts)) now := b.clock.Now() for i := range starts { start := &starts[i] for _, index := range start.Indices { lrpKey := models.NewActualLRPKey(start.ProcessGuid, int32(index), start.Domain) auction := auctiontypes.NewLRPAuction(rep.NewLRP(lrpKey, start.Resource), now) auctions = append(auctions, auction) } } b.lock.Lock() b.lrpAuctions = append(b.lrpAuctions, auctions...) b.claimToHaveWork() b.lock.Unlock() }
var metricSender *fake.FakeMetricSender BeforeEach(func() { metricSender = fake.NewFakeMetricSender() metrics.Initialize(metricSender, nil) delegate = auctionmetricemitterdelegate.New() }) Describe("AuctionCompleted", func() { It("should adjust the metric counters", func() { resource := rep.NewResource(10, 10, "linux") delegate.AuctionCompleted(auctiontypes.AuctionResults{ SuccessfulLRPs: []auctiontypes.LRPAuction{ { LRP: rep.NewLRP(models.NewActualLRPKey("successful-start", 0, "domain"), resource), }, }, SuccessfulTasks: []auctiontypes.TaskAuction{ { Task: rep.NewTask("successful-task", "domain", resource), }, }, FailedLRPs: []auctiontypes.LRPAuction{ { LRP: rep.NewLRP(models.NewActualLRPKey("insufficient-capacity", 0, "domain"), resource), AuctionRecord: auctiontypes.AuctionRecord{PlacementError: rep.ErrorInsufficientResources.Error()}, }, { LRP: rep.NewLRP(models.NewActualLRPKey("incompatible-stacks", 0, "domain"), resource), AuctionRecord: auctiontypes.AuctionRecord{PlacementError: auctiontypes.ErrorCellMismatch.Error()},
func BuildLRPAuctionWithPlacementError(processGuid, domain string, index int, rootFS string, memoryMB, diskMB int32, queueTime time.Time, placementError string) auctiontypes.LRPAuction { lrpKey := models.NewActualLRPKey(processGuid, int32(index), domain) a := auctiontypes.NewLRPAuction(rep.NewLRP(lrpKey, rep.NewResource(memoryMB, diskMB, rootFS)), queueTime) a.PlacementError = placementError return a }
func BuildLRPAuction(processGuid, domain string, index int, rootFS string, memoryMB, diskMB int32, queueTime time.Time) auctiontypes.LRPAuction { lrpKey := models.NewActualLRPKey(processGuid, int32(index), domain) return auctiontypes.NewLRPAuction(rep.NewLRP(lrpKey, rep.NewResource(memoryMB, diskMB, rootFS)), queueTime) }
func BuildLRP(guid, domain string, index int, rootFS string, memoryMB, diskMB int32) *rep.LRP { lrpKey := models.NewActualLRPKey(guid, int32(index), domain) lrp := rep.NewLRP(lrpKey, rep.NewResource(memoryMB, diskMB, rootFS)) return &lrp }
"github.com/cloudfoundry-incubator/auction/simulation/util" "github.com/cloudfoundry-incubator/auction/simulation/visualization" "github.com/cloudfoundry-incubator/auctioneer" "github.com/cloudfoundry-incubator/bbs/models" "github.com/cloudfoundry-incubator/rep" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Auction", func() { var initialDistributions map[int][]rep.LRP var linuxRootFSURL = models.PreloadedRootFS(linuxStack) newLRP := func(processGuid string, index int, memoryMB int) rep.LRP { lrpKey := models.NewActualLRPKey(processGuid, int32(index), "domain") return rep.NewLRP(lrpKey, rep.NewResource(int32(memoryMB), 1, linuxRootFSURL)) } generateUniqueLRPs := func(numInstances int, index int, memoryMB int) []rep.LRP { instances := []rep.LRP{} for i := 0; i < numInstances; i++ { instances = append(instances, newLRP(util.NewGrayscaleGuid("AAA"), index, memoryMB)) } return instances } newLRPStartAuction := func(processGuid string, index int, memoryMB int32) auctioneer.LRPStartRequest { return auctioneer.NewLRPStartRequest(processGuid, "domain", []int{index}, rep.NewResource(memoryMB, 1, linuxRootFSURL)) } generateUniqueLRPStartAuctions := func(numInstances int, memoryMB int32) []auctioneer.LRPStartRequest {
// State currently does not return tasks or lrp rootfs, because the // auctioneer currently does not need them. func (a *AuctionCellRep) State() (rep.CellState, error) { logger := a.logger.Session("auction-state") logger.Info("providing") containers, err := a.client.ListContainers(executor.Tags{}) if err != nil { logger.Error("failed-to-fetch-containers", err) return rep.CellState{}, err } totalResources, err := a.client.TotalResources() if err != nil { logger.Error("failed-to-get-total-resources", err) return rep.CellState{}, err } availableResources, err := a.client.RemainingResourcesFrom(containers) if err != nil { logger.Error("failed-to-get-remaining-resource", err) return rep.CellState{}, err } var key *models.ActualLRPKey var keyErr error lrps := []rep.LRP{} tasks := []rep.Task{} for i := range containers { container := &containers[i] resource := rep.Resource{MemoryMB: int32(container.MemoryMB), DiskMB: int32(container.DiskMB)} if container.Tags == nil { logger.Error("failed-to-extract-container-tags", nil) continue } switch container.Tags[rep.LifecycleTag] { case rep.LRPLifecycle: key, keyErr = rep.ActualLRPKeyFromTags(container.Tags) if keyErr != nil { logger.Error("failed-to-extract-key", keyErr) continue } lrps = append(lrps, rep.NewLRP(*key, resource)) case rep.TaskLifecycle: domain := container.Tags[rep.DomainTag] tasks = append(tasks, rep.NewTask(container.Guid, domain, resource)) } } state := rep.NewCellState( a.rootFSProviders, a.convertResources(availableResources), a.convertResources(totalResources), lrps, tasks, a.zone, a.evacuationReporter.Evacuating(), ) a.logger.Info("provided", lager.Data{ "available-resources": state.AvailableResources, "total-resources": state.TotalResources, "num-lrps": len(state.LRPs), "zone": state.Zone, "evacuating": state.Evacuating, }) return state, nil }
})) Expect(state.AvailableResources).To(Equal(rep.Resources{ MemoryMB: int32(availableResources.MemoryMB), DiskMB: int32(availableResources.DiskMB), Containers: availableResources.Containers, })) Expect(state.TotalResources).To(Equal(rep.Resources{ MemoryMB: int32(totalResources.MemoryMB), DiskMB: int32(totalResources.DiskMB), Containers: totalResources.Containers, })) Expect(state.LRPs).To(ConsistOf([]rep.LRP{ rep.NewLRP(models.NewActualLRPKey("the-first-app-guid", 17, "domain"), rep.NewResource(20, 10, "")), rep.NewLRP(models.NewActualLRPKey("the-second-app-guid", 92, "domain"), rep.NewResource(40, 30, "")), })) Expect(state.Tasks).To(ConsistOf([]rep.Task{ rep.NewTask("da-task", "domain", rep.NewResource(40, 30, "")), })) }) Context("when the cell is not healthy", func() { BeforeEach(func() { client.HealthyReturns(false) }) It("errors when reporting state", func() { _, err := cellRep.State()