/* AbstractQueue and BlockingQueue methods */ /// <summary> /// Put and offer follow the same pattern: /// 1. /// </summary> /// <remarks> /// Put and offer follow the same pattern: /// 1. Get a priorityLevel from the scheduler /// 2. Get the nth sub-queue matching this priorityLevel /// 3. delegate the call to this sub-queue. /// But differ in how they handle overflow: /// - Put will move on to the next queue until it lands on the last queue /// - Offer does not attempt other queues on overflow /// </remarks> /// <exception cref="System.Exception"/> public virtual void Put(E e) { int priorityLevel = scheduler.GetPriorityLevel(e); int numLevels = this.queues.Count; while (true) { BlockingQueue <E> q = this.queues[priorityLevel]; bool res = q.Offer(e); if (!res) { // Update stats this.overflowedCalls[priorityLevel].GetAndIncrement(); // If we failed to insert, try again on the next level priorityLevel++; if (priorityLevel == numLevels) { // That was the last one, we will block on put in the last queue // Delete this line to drop the call this.queues[priorityLevel - 1].Put(e); break; } } else { break; } } SignalNotEmpty(); }
public TestFairCallQueue() { { RpcScheduler sched = Org.Mockito.Mockito.Mock <RpcScheduler>(); Org.Mockito.Mockito.When(sched.GetPriorityLevel(Matchers.Any <Schedulable>())).ThenReturn (0); alwaysZeroScheduler = sched; } }
public virtual void TestAllQueuesFullRemainingCapacity() { RpcScheduler sched = Org.Mockito.Mockito.Mock <RpcScheduler>(); Org.Mockito.Mockito.When(sched.GetPriorityLevel(Matchers.Any <Schedulable>())).ThenReturn (0, 0, 0, 0, 0, 1, 1, 1, 1, 1); fcq.SetScheduler(sched); while (fcq.Offer(MockCall("c"))) { } Assert.Equal(0, fcq.RemainingCapacity()); Assert.Equal(10, fcq.Count); }
public virtual void TestQueuesPartialFilledRemainingCapacity() { RpcScheduler sched = Org.Mockito.Mockito.Mock <RpcScheduler>(); Org.Mockito.Mockito.When(sched.GetPriorityLevel(Matchers.Any <Schedulable>())).ThenReturn (0, 1, 0, 1, 0); fcq.SetScheduler(sched); for (int i = 0; i < 5; i++) { fcq.Offer(MockCall("c")); } Assert.Equal(5, fcq.RemainingCapacity()); Assert.Equal(5, fcq.Count); }
public virtual void TestOfferSucceedsWhenScheduledLowPriority() { // Scheduler will schedule into queue 0 x 5, then queue 1 RpcScheduler sched = Org.Mockito.Mockito.Mock <RpcScheduler>(); Org.Mockito.Mockito.When(sched.GetPriorityLevel(Matchers.Any <Schedulable>())).ThenReturn (0, 0, 0, 0, 0, 1, 0); fcq.SetScheduler(sched); for (int i = 0; i < 5; i++) { Assert.True(fcq.Offer(MockCall("c"))); } Assert.True(fcq.Offer(MockCall("c"))); Assert.Equal(6, fcq.Count); }
/// <exception cref="System.Exception"/> public virtual void TestTakeTriesNextQueue() { // Make a FCQ filled with calls in q 1 but empty in q 0 RpcScheduler q1Scheduler = Org.Mockito.Mockito.Mock <RpcScheduler>(); Org.Mockito.Mockito.When(q1Scheduler.GetPriorityLevel(Matchers.Any <Schedulable>() )).ThenReturn(1); fcq.SetScheduler(q1Scheduler); // A mux which only draws from q 0 RpcMultiplexer q0mux = Org.Mockito.Mockito.Mock <RpcMultiplexer>(); Org.Mockito.Mockito.When(q0mux.GetAndAdvanceCurrentIndex()).ThenReturn(0); fcq.SetMultiplexer(q0mux); Schedulable call = MockCall("c"); fcq.Put(call); // Take from q1 even though mux said q0, since q0 empty Assert.Equal(call, fcq.Take()); Assert.Equal(0, fcq.Count); }