/// <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);
        }
示例#2
0
        /// <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));
            }
        }