/** * Does nothing but exercise a {@link CallRunner} outside of {@link RpcServer} context. */ @Test public void testSimpleCall() { RpcServerInterface mockRpcServer = Mockito.mock(RpcServerInterface.class); Mockito.when(mockRpcServer.isStarted()).thenReturn(true); ServerCall mockCall = Mockito.mock(ServerCall.class); CallRunner cr = new CallRunner(mockRpcServer, mockCall); cr.setStatus(new MonitoredRPCHandlerImpl()); cr.run(); } }
this.rpcServer.addCallSize(call.getSize() * -1); cleanup();
private CallRunner createMockTask() { ServerCall call = mock(ServerCall.class); CallRunner task = mock(CallRunner.class); when(task.getRpcCall()).thenReturn(call); doAnswer(new Answer<Void>() { @Override public Void answer (InvocationOnMock invocation) throws Throwable { callExecutionCount.incrementAndGet(); Thread.sleep(1000); return null; } }).when(task).run(); return task; }
@Override public boolean dispatch(CallRunner callTask) throws InterruptedException, IOException { ServerCall call = callTask.getCall(); int priority = call.getHeader().getPriority(); if (indexPriority == priority) { return indexCallExecutor.dispatch(callTask); } else if (metadataPriority == priority) { return metadataCallExecutor.dispatch(callTask); } else { return delegate.dispatch(callTask); } }
/** * @param callRunner to validate * @return true if this call needs to be skipped based on call timestamp * and internal queue state (deemed overloaded). */ private boolean needToDrop(CallRunner callRunner) { long now = EnvironmentEdgeManager.currentTime(); long callDelay = now - callRunner.getRpcCall().getReceiveTime(); long localMinDelay = this.minDelay; // Try and determine if we should reset // the delay time and determine overload if (now > intervalTime && !resetDelay.get() && !resetDelay.getAndSet(true)) { intervalTime = now + codelInterval; isOverloaded.set(localMinDelay > codelTargetDelay); } // If it looks like we should reset the delay // time do it only once on one thread if (resetDelay.get() && resetDelay.getAndSet(false)) { minDelay = callDelay; // we just reset the delay dunno about how this will work return false; } else if (callDelay < localMinDelay) { minDelay = callDelay; } return isOverloaded.get() && callDelay > 2 * codelTargetDelay; }
@Test public void testCallQueueInfo() throws IOException, InterruptedException { ThreadPoolExecutor rpcExecutor; RpcScheduler scheduler = new FifoRpcScheduler( conf, 1); scheduler.init(CONTEXT); // Set number of handlers to a minimum value disableHandlers(scheduler); int totalCallMethods = 30; int unableToDispatch = 0; for (int i = totalCallMethods; i>0; i--) { CallRunner task = createMockTask(); task.setStatus(new MonitoredRPCHandlerImpl()); if(!scheduler.dispatch(task)) { unableToDispatch++; } Thread.sleep(10); } CallQueueInfo callQueueInfo = scheduler.getCallQueueInfo(); int executionCount = callExecutionCount.get(); int callQueueSize = 0; for (String callQueueName:callQueueInfo.getCallQueueNames()) { for (String calledMethod: callQueueInfo.getCalledMethodNames(callQueueName)) { callQueueSize += callQueueInfo.getCallMethodCount(callQueueName, calledMethod); } } assertEquals(totalCallMethods - unableToDispatch, callQueueSize + executionCount); scheduler.stop(); }
this.addr, timeout, this.callCleanup); if (!this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) { this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize()); this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);
@Override public void run() { callRunner.run(); }
/** * Behaves as {@link LinkedBlockingQueue#take()}, except it will silently * skip all calls which it thinks should be dropped. * * @return the head of this queue * @throws InterruptedException if interrupted while waiting */ @Override public CallRunner take() throws InterruptedException { CallRunner cr; while(true) { if (((double) queue.size() / this.maxCapacity) > lifoThreshold) { numLifoModeSwitches.increment(); cr = queue.takeLast(); } else { cr = queue.takeFirst(); } if (needToDrop(cr)) { numGeneralCallsDropped.increment(); cr.drop(); } else { return cr; } } }
private void doAnswerTaskExecution(final CallRunner callTask, final ArrayList<Integer> results, final int value, final int sleepInterval) { callTask.setStatus(new MonitoredRPCHandlerImpl()); doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) { synchronized (results) { results.add(value); } Threads.sleepWithoutInterrupt(sleepInterval); return null; } }).when(callTask).run(); }
private void dispatchCallWithPriority(RpcScheduler scheduler, int priority) throws Exception { CallRunner task = Mockito.mock(CallRunner.class); RequestHeader header = RequestHeader.newBuilder().setPriority(priority).build(); RpcServer server = RpcServerFactory.createRpcServer(null, "test-rpcserver", Lists.newArrayList(new BlockingServiceAndInterface( SERVICE, null)), isa, conf, scheduler); ServerCall call = Mockito.mock(ServerCall.class); when(call.getHeader()).thenReturn(header); when(call.getRequestUser()).thenReturn(Optional.empty()); Mockito.when(task.getCall()).thenReturn(call); scheduler.dispatch(task); Mockito.verify(task).getCall(); Mockito.verifyNoMoreInteractions(task); server.stop(); } }
private CallRunner createMockTask() { ServerCall call = mock(ServerCall.class); CallRunner task = mock(CallRunner.class); when(task.getRpcCall()).thenReturn(call); return task; }
@Test public void testCallQueueInfo() throws IOException, InterruptedException { PriorityFunction qosFunction = mock(PriorityFunction.class); RpcScheduler scheduler = new SimpleRpcScheduler( conf, 0, 0, 0, qosFunction, 0); scheduler.init(CONTEXT); // Set the handlers to zero. So that number of requests in call Queue can be tested scheduler = disableHandlers(scheduler); scheduler.start(); int totalCallMethods = 10; for (int i = totalCallMethods; i>0; i--) { CallRunner task = createMockTask(); task.setStatus(new MonitoredRPCHandlerImpl()); scheduler.dispatch(task); } CallQueueInfo callQueueInfo = scheduler.getCallQueueInfo(); for (String callQueueName:callQueueInfo.getCallQueueNames()) { for (String calledMethod: callQueueInfo.getCalledMethodNames(callQueueName)) { assertEquals(totalCallMethods, callQueueInfo.getCallMethodCount(callQueueName, calledMethod)); } } scheduler.stop(); }
totalRequestSize, traceInfo, this.addr); if (!scheduler.dispatch(new CallRunner(RpcServer.this, call))) { callQueueSize.add(-1 * call.getSize());
@Override public CallRunner poll() { CallRunner cr; boolean switched = false; while(true) { if (((double) queue.size() / this.maxCapacity) > lifoThreshold) { // Only count once per switch. if (!switched) { switched = true; numLifoModeSwitches.increment(); } cr = queue.pollLast(); } else { switched = false; cr = queue.pollFirst(); } if (cr == null) { return cr; } if (needToDrop(cr)) { numGeneralCallsDropped.increment(); cr.drop(); } else { return cr; } } }
/** * Does nothing but exercise a {@link CallRunner} outside of {@link RpcServer} context. */ @Test public void testSimpleCall() { RpcServerInterface mockRpcServer = Mockito.mock(RpcServerInterface.class); Mockito.when(mockRpcServer.isStarted()).thenReturn(true); ServerCall mockCall = Mockito.mock(ServerCall.class); CallRunner cr = new CallRunner(mockRpcServer, mockCall); cr.setStatus(new MonitoredRPCHandlerImpl()); cr.run(); } }
@Override public int compare(CallRunner a, CallRunner b) { RpcServer.Call callA = a.getCall(); RpcServer.Call callB = b.getCall(); long deadlineA = priority.getDeadline(callA.getHeader(), callA.param); long deadlineB = priority.getDeadline(callB.getHeader(), callB.param); deadlineA = callA.timestamp + Math.min(deadlineA, maxDelay); deadlineB = callB.timestamp + Math.min(deadlineB, maxDelay); return (int)(deadlineA - deadlineB); } }
private CallRunner createMockTask(AtomicInteger callExecutionCount, boolean isRegionServerReportTask) { CallRunner task = mock(CallRunner.class); ServerCall call = mock(ServerCall.class); when(task.getRpcCall()).thenReturn(call); when(call.getHeader()).thenReturn(RPCProtos.RequestHeader.newBuilder() .setMethodName(isRegionServerReportTask ? REGION_SERVER_REPORT : OTHER).build()); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { callExecutionCount.incrementAndGet(); Thread.sleep(1000); return null; } }).when(task).run(); return task; }