func (sc *SchedulerCore) acceptOffer(driver sched.SchedulerDriver, offer *mesos.Offer, operations []*mesos.Offer_Operation) { log.Infof("Accepting OfferID: %+v, Operations: %+v", *offer.Id.Value, operations) var status mesos.Status var err error if sc.compatibilityMode { tasks := []*mesos.TaskInfo{} for _, operation := range operations { if *operation.Type == mesos.Offer_Operation_LAUNCH { tasks = operation.Launch.TaskInfos } } status, err = driver.LaunchTasks([]*mesos.OfferID{offer.Id}, tasks, &mesos.Filters{RefuseSeconds: proto.Float64(OFFER_INTERVAL)}) } else { status, err = driver.AcceptOffers([]*mesos.OfferID{offer.Id}, operations, &mesos.Filters{RefuseSeconds: proto.Float64(OFFER_INTERVAL)}) } if status != mesos.Status_DRIVER_RUNNING { log.Fatal("Driver not running, while trying to accept offers") } if err != nil { log.Panic("Failed to launch tasks: ", err) } }
func (sched *ExampleScheduler) ResourceOffers(driver sched.SchedulerDriver, offers []*mesos.Offer) { for _, offer := range offers { operations := []*mesos.Offer_Operation{} resourcesToCreate := []*mesos.Resource{} resourcesToDestroy := []*mesos.Resource{} resourcesToReserve := []*mesos.Resource{} resourcesToUnreserve := []*mesos.Resource{} taskInfosToLaunch := []*mesos.TaskInfo{} totalUnreserved := 0 unreservedCpus, unreservedMem, unreservedDisk := getUnreservedResources(offer.Resources) reservedCpus, reservedMem, reservedDisk := getReservedResources(offer.Resources) log.Infoln("Received Offer <", offer.Id.GetValue(), "> with unreserved cpus=", unreservedCpus, " mem=", unreservedMem, " disk=", unreservedDisk) log.Infoln("Received Offer <", offer.Id.GetValue(), "> with reserved cpus=", reservedCpus, " mem=", reservedMem, " disk=", reservedDisk) for _, task := range sched.tasks { switch task.state { case InitState: if CPUS_PER_TASK <= unreservedCpus && MEM_PER_TASK <= unreservedMem && DISK_PER_TASK <= unreservedDisk { resourcesToReserve = append(resourcesToReserve, []*mesos.Resource{ util.NewScalarResourceWithReservation("cpus", CPUS_PER_TASK, *mesosAuthPrincipal, *role), util.NewScalarResourceWithReservation("mem", MEM_PER_TASK, *mesosAuthPrincipal, *role), util.NewScalarResourceWithReservation("disk", DISK_PER_TASK, *mesosAuthPrincipal, *role), }...) resourcesToCreate = append(resourcesToCreate, util.NewVolumeResourceWithReservation(DISK_PER_TASK, task.containerPath, task.persistenceId, mesos.Volume_RW.Enum(), *mesosAuthPrincipal, *role)) task.state = RequestedReservationState unreservedCpus = unreservedCpus - CPUS_PER_TASK unreservedMem = unreservedMem - MEM_PER_TASK unreservedDisk = unreservedDisk - DISK_PER_TASK } case RequestedReservationState: if CPUS_PER_TASK <= reservedCpus && MEM_PER_TASK <= reservedMem && DISK_PER_TASK <= reservedDisk && resourcesHaveVolume(offer.Resources, task.persistenceId) { taskId := &mesos.TaskID{ Value: proto.String(task.name), } taskInfo := &mesos.TaskInfo{ Name: proto.String("go-task-" + taskId.GetValue()), TaskId: taskId, SlaveId: offer.SlaveId, Executor: task.executor, Resources: []*mesos.Resource{ util.NewScalarResourceWithReservation("cpus", CPUS_PER_TASK, *mesosAuthPrincipal, *role), util.NewScalarResourceWithReservation("mem", MEM_PER_TASK, *mesosAuthPrincipal, *role), util.NewVolumeResourceWithReservation(DISK_PER_TASK, task.containerPath, task.persistenceId, mesos.Volume_RW.Enum(), *mesosAuthPrincipal, *role), }, } taskInfosToLaunch = append(taskInfosToLaunch, taskInfo) task.state = LaunchedState reservedCpus = reservedCpus - CPUS_PER_TASK reservedMem = reservedMem - MEM_PER_TASK reservedDisk = reservedDisk - DISK_PER_TASK log.Infof("Prepared task: %s with offer %s for launch\n", taskInfo.GetName(), offer.Id.GetValue()) } case FinishedState: resourcesToDestroy = append(resourcesToDestroy, util.NewVolumeResourceWithReservation(DISK_PER_TASK, task.containerPath, task.persistenceId, mesos.Volume_RW.Enum(), *mesosAuthPrincipal, *role)) resourcesToUnreserve = append(resourcesToUnreserve, []*mesos.Resource{ util.NewScalarResourceWithReservation("cpus", CPUS_PER_TASK, *mesosAuthPrincipal, *role), util.NewScalarResourceWithReservation("mem", MEM_PER_TASK, *mesosAuthPrincipal, *role), util.NewScalarResourceWithReservation("disk", DISK_PER_TASK, *mesosAuthPrincipal, *role), }...) task.state = UnreservedState case UnreservedState: totalUnreserved = totalUnreserved + 1 } } // Clean up reservations we no longer need if len(resourcesToReserve) == 0 && len(resourcesToCreate) == 0 && len(taskInfosToLaunch) == 0 { if reservedCpus >= 0.0 { resourcesToUnreserve = append(resourcesToUnreserve, util.NewScalarResourceWithReservation("cpus", reservedCpus, *mesosAuthPrincipal, *role)) } if reservedMem >= 0.0 { resourcesToUnreserve = append(resourcesToUnreserve, util.NewScalarResourceWithReservation("mem", reservedCpus, *mesosAuthPrincipal, *role)) } if reservedDisk >= 0.0 { filtered := util.FilterResources(offer.Resources, func(res *mesos.Resource) bool { return res.GetName() == "disk" && res.Reservation != nil && res.Disk != nil }) for _, volume := range filtered { resourcesToDestroy = append(resourcesToDestroy, util.NewVolumeResourceWithReservation( volume.GetScalar().GetValue(), volume.Disk.Volume.GetContainerPath(), volume.Disk.Persistence.GetId(), volume.Disk.Volume.Mode, *mesosAuthPrincipal, *role)) } resourcesToUnreserve = append(resourcesToUnreserve, util.NewScalarResourceWithReservation("mem", reservedDisk, *mesosAuthPrincipal, *role)) } } // Make a single operation per type if len(resourcesToReserve) > 0 { operations = append(operations, util.NewReserveOperation(resourcesToReserve)) } if len(resourcesToCreate) > 0 { operations = append(operations, util.NewCreateOperation(resourcesToCreate)) } if len(resourcesToUnreserve) > 0 { operations = append(operations, util.NewUnreserveOperation(resourcesToUnreserve)) } if len(resourcesToDestroy) > 0 { operations = append(operations, util.NewDestroyOperation(resourcesToDestroy)) } if len(taskInfosToLaunch) > 0 { operations = append(operations, util.NewLaunchOperation(taskInfosToLaunch)) } log.Infoln("Accepting offers with ", len(operations), "operations for offer", offer.Id.GetValue()) refuseSeconds := 5.0 if len(operations) == 0 { refuseSeconds = 5.0 } driver.AcceptOffers([]*mesos.OfferID{offer.Id}, operations, &mesos.Filters{RefuseSeconds: proto.Float64(refuseSeconds)}) if totalUnreserved >= len(sched.tasks) { log.Infoln("Total tasks completed and unreserved, stopping framework.") driver.Stop(false) } } }