/// <exception cref="Org.Apache.Hadoop.Yarn.Server.Resourcemanager.Reservation.Exceptions.PlanningException /// "/> /// <exception cref="System.Exception"/> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException"/> protected internal virtual void TestPlanFollower(bool isMove) { // Initialize plan based on move flag plan = new InMemoryPlan(scheduler.GetRootQueueMetrics(), policy, mAgent, scheduler .GetClusterResource(), 1L, res, scheduler.GetMinimumResourceCapability(), maxAlloc , "dedicated", null, isMove); // add a few reservations to the plan long ts = Runtime.CurrentTimeMillis(); ReservationId r1 = ReservationId.NewInstance(ts, 1); int[] f1 = new int[] { 10, 10, 10, 10, 10 }; NUnit.Framework.Assert.IsTrue(plan.ToString(), plan.AddReservation(new InMemoryReservationAllocation (r1, null, "u3", "dedicated", 0, 0 + f1.Length, ReservationSystemTestUtil.GenerateAllocation (0L, 1L, f1), res, minAlloc))); ReservationId r2 = ReservationId.NewInstance(ts, 2); NUnit.Framework.Assert.IsTrue(plan.ToString(), plan.AddReservation(new InMemoryReservationAllocation (r2, null, "u3", "dedicated", 3, 3 + f1.Length, ReservationSystemTestUtil.GenerateAllocation (3L, 1L, f1), res, minAlloc))); ReservationId r3 = ReservationId.NewInstance(ts, 3); int[] f2 = new int[] { 0, 10, 20, 10, 0 }; NUnit.Framework.Assert.IsTrue(plan.ToString(), plan.AddReservation(new InMemoryReservationAllocation (r3, null, "u4", "dedicated", 10, 10 + f2.Length, ReservationSystemTestUtil.GenerateAllocation (10L, 1L, f2), res, minAlloc))); AbstractSchedulerPlanFollower planFollower = CreatePlanFollower(); Org.Mockito.Mockito.When(mClock.GetTime()).ThenReturn(0L); planFollower.Run(); Queue q = GetReservationQueue(r1.ToString()); AssertReservationQueueExists(r1); // submit an app to r1 string user_0 = "test-user"; ApplicationId appId = ApplicationId.NewInstance(0, 1); ApplicationAttemptId appAttemptId_0 = ApplicationAttemptId.NewInstance(appId, 0); AppAddedSchedulerEvent addAppEvent = new AppAddedSchedulerEvent(appId, q.GetQueueName (), user_0); scheduler.Handle(addAppEvent); AppAttemptAddedSchedulerEvent appAttemptAddedEvent = new AppAttemptAddedSchedulerEvent (appAttemptId_0, false); scheduler.Handle(appAttemptAddedEvent); // initial default reservation queue should have no apps Queue defQ = GetDefaultQueue(); NUnit.Framework.Assert.AreEqual(0, GetNumberOfApplications(defQ)); AssertReservationQueueExists(r1, 0.1, 0.1); NUnit.Framework.Assert.AreEqual(1, GetNumberOfApplications(q)); AssertReservationQueueDoesNotExist(r2); AssertReservationQueueDoesNotExist(r3); Org.Mockito.Mockito.When(mClock.GetTime()).ThenReturn(3L); planFollower.Run(); NUnit.Framework.Assert.AreEqual(0, GetNumberOfApplications(defQ)); AssertReservationQueueExists(r1, 0.1, 0.1); NUnit.Framework.Assert.AreEqual(1, GetNumberOfApplications(q)); AssertReservationQueueExists(r2, 0.1, 0.1); AssertReservationQueueDoesNotExist(r3); Org.Mockito.Mockito.When(mClock.GetTime()).ThenReturn(10L); planFollower.Run(); q = GetReservationQueue(r1.ToString()); if (isMove) { // app should have been moved to default reservation queue NUnit.Framework.Assert.AreEqual(1, GetNumberOfApplications(defQ)); NUnit.Framework.Assert.IsNull(q); } else { // app should be killed NUnit.Framework.Assert.AreEqual(0, GetNumberOfApplications(defQ)); NUnit.Framework.Assert.IsNotNull(q); AppAttemptRemovedSchedulerEvent appAttemptRemovedEvent = new AppAttemptRemovedSchedulerEvent (appAttemptId_0, RMAppAttemptState.Killed, false); scheduler.Handle(appAttemptRemovedEvent); } AssertReservationQueueDoesNotExist(r2); AssertReservationQueueExists(r3, 0, 1.0); Org.Mockito.Mockito.When(mClock.GetTime()).ThenReturn(11L); planFollower.Run(); if (isMove) { // app should have been moved to default reservation queue NUnit.Framework.Assert.AreEqual(1, GetNumberOfApplications(defQ)); } else { // app should be killed NUnit.Framework.Assert.AreEqual(0, GetNumberOfApplications(defQ)); } AssertReservationQueueDoesNotExist(r1); AssertReservationQueueDoesNotExist(r2); AssertReservationQueueExists(r3, 0.1, 0.1); Org.Mockito.Mockito.When(mClock.GetTime()).ThenReturn(12L); planFollower.Run(); AssertReservationQueueDoesNotExist(r1); AssertReservationQueueDoesNotExist(r2); AssertReservationQueueExists(r3, 0.2, 0.2); Org.Mockito.Mockito.When(mClock.GetTime()).ThenReturn(16L); planFollower.Run(); AssertReservationQueueDoesNotExist(r1); AssertReservationQueueDoesNotExist(r2); AssertReservationQueueDoesNotExist(r3); VerifyCapacity(defQ); }
/// <exception cref="Org.Apache.Hadoop.Yarn.Server.Resourcemanager.Reservation.Exceptions.PlanningException /// "/> /// <exception cref="Org.Apache.Hadoop.Yarn.Server.Resourcemanager.Reservation.Exceptions.ContractValidationException /// "/> private bool ComputeAllocation(ReservationId reservationId, string user, Plan plan , ReservationDefinition contract, ReservationAllocation oldReservation) { Log.Info("placing the following ReservationRequest: " + contract); Resource totalCapacity = plan.GetTotalCapacity(); // Here we can addd logic to adjust the ResourceDefinition to account for // system "imperfections" (e.g., scheduling delays for large containers). // Align with plan step conservatively (i.e., ceil arrival, and floor // deadline) long earliestStart = contract.GetArrival(); long step = plan.GetStep(); if (earliestStart % step != 0) { earliestStart = earliestStart + (step - (earliestStart % step)); } long deadline = contract.GetDeadline() - contract.GetDeadline() % plan.GetStep(); // setup temporary variables to handle time-relations between stages and // intermediate answers long curDeadline = deadline; long oldDeadline = -1; IDictionary <ReservationInterval, ReservationRequest> allocations = new Dictionary <ReservationInterval, ReservationRequest>(); RLESparseResourceAllocation tempAssigned = new RLESparseResourceAllocation(plan.GetResourceCalculator (), plan.GetMinimumAllocation()); IList <ReservationRequest> stages = contract.GetReservationRequests().GetReservationResources (); ReservationRequestInterpreter type = contract.GetReservationRequests().GetInterpreter (); // Iterate the stages in backward from deadline for (ListIterator <ReservationRequest> li = stages.ListIterator(stages.Count); li. HasPrevious();) { ReservationRequest currentReservationStage = li.Previous(); // validate the RR respect basic constraints ValidateInput(plan, currentReservationStage, totalCapacity); // run allocation for a single stage IDictionary <ReservationInterval, ReservationRequest> curAlloc = PlaceSingleStage( plan, tempAssigned, currentReservationStage, earliestStart, curDeadline, oldReservation , totalCapacity); if (curAlloc == null) { // if we did not find an allocation for the currentReservationStage // return null, unless the ReservationDefinition we are placing is of // type ANY if (type != ReservationRequestInterpreter.RAny) { throw new PlanningException("The GreedyAgent" + " couldn't find a valid allocation for your request" ); } else { continue; } } else { // if we did find an allocation add it to the set of allocations allocations.PutAll(curAlloc); // if this request is of type ANY we are done searching (greedy) // and can return the current allocation (break-out of the search) if (type == ReservationRequestInterpreter.RAny) { break; } // if the request is of ORDER or ORDER_NO_GAP we constraint the next // round of allocation to precede the current allocation, by setting // curDeadline if (type == ReservationRequestInterpreter.ROrder || type == ReservationRequestInterpreter .ROrderNoGap) { curDeadline = FindEarliestTime(curAlloc.Keys); // for ORDER_NO_GAP verify that the allocation found so far has no // gap, return null otherwise (the greedy procedure failed to find a // no-gap // allocation) if (type == ReservationRequestInterpreter.ROrderNoGap && oldDeadline > 0) { if (oldDeadline - FindLatestTime(curAlloc.Keys) > plan.GetStep()) { throw new PlanningException("The GreedyAgent" + " couldn't find a valid allocation for your request" ); } } // keep the variable oldDeadline pointing to the last deadline we // found oldDeadline = curDeadline; } } } // / If we got here is because we failed to find an allocation for the // ReservationDefinition give-up and report failure to the user if (allocations.IsEmpty()) { throw new PlanningException("The GreedyAgent" + " couldn't find a valid allocation for your request" ); } // create reservation with above allocations if not null/empty ReservationRequest ZeroRes = ReservationRequest.NewInstance(Resource.NewInstance( 0, 0), 0); long firstStartTime = FindEarliestTime(allocations.Keys); // add zero-padding from arrival up to the first non-null allocation // to guarantee that the reservation exists starting at arrival if (firstStartTime > earliestStart) { allocations[new ReservationInterval(earliestStart, firstStartTime)] = ZeroRes; firstStartTime = earliestStart; } // consider to add trailing zeros at the end for simmetry // Actually add/update the reservation in the plan. // This is subject to validation as other agents might be placing // in parallel and there might be sharing policies the agent is not // aware off. ReservationAllocation capReservation = new InMemoryReservationAllocation(reservationId , contract, user, plan.GetQueueName(), firstStartTime, FindLatestTime(allocations .Keys), allocations, plan.GetResourceCalculator(), plan.GetMinimumAllocation()); if (oldReservation != null) { return(plan.UpdateReservation(capReservation)); } else { return(plan.AddReservation(capReservation)); } }