/** * Execute some code and update the specified counter. This invocation increments the counter by 1 * * @param r * A Runnable or closure with no args and no return values * @param counterName * The name of the counter to update */ default void counted(Runnable r, String counterName) { counted(r, counterName, 1L); }
/** * Execute some code and update the specified event rate metric. This invocation represents a single event. * * @param r * A Runnable to run or a closure with no arguments and no returns * @param meterName * The meter to update */ default void metered(Runnable r, String meterName) { metered(r, meterName, 1L); }
@Override public CompletableFuture<ResponseInfo<Map<String, String>>> execute(final RequestInfo<Object> request, Executor longRunningTaskExecutor, ChannelHandlerContext ctx) { String nettyWorkerThreadName = Thread.currentThread().getName(); //nettyWorkerThreadsUsed.add(nettyWorkerThreadName); CompletableFuture<ResponseInfo<Map<String, String>>> result = CompletableFuture.supplyAsync(() -> doEndpointWork(request.getQueryParamSingle("error")), executor); return result; }
metricsListener.onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, state); .addListener((ChannelFutureListener) channelFuture -> { if (channelFuture.isSuccess()) metricsListener.onEvent(ServerMetricsEvent.RESPONSE_SENT, stateCopy); else { metricsListener.onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, null);
@Before public void setUp() throws Exception { executor = Executors.newCachedThreadPool(); serverConfig = new MetricsTestConfig(); metricsListener = (CodahaleMetricsListener) serverConfig.metricsListener(); endpointMetricsHandler = (EndpointMetricsHandlerDefaultImpl) metricsListener.getEndpointMetricsHandler(); assertTrue(serverConfig.endpointsPort() > 0); logger.info("Dynamically chose server port {}", serverConfig.endpointsPort()); nonblockingEndpointUrl = "http://127.0.0.1:" + serverConfig.endpointsPort() + NON_BLOCKING_MATCHING_PATH; server = new Server(serverConfig); server.startup(); // Perform a "warmup" to get the Server ready to go - the first call is always slower than normal. List<Future<?>> warmupCalls = new ArrayList<>(); warmupCalls.add(sendServerRequest(nonblockingEndpointUrl)); for (Future f : warmupCalls) { f.get(); } }
protected void doServerAsyncProcessingVerificationTestForUrl(String endpointUrl, boolean expectNettyWorkerThreadToBeDifferentThanExecutor) throws ExecutionException, InterruptedException { // Clear the data and run the test clearDataForNewTest(); List<Future<Map<String, String>>> futures = new ArrayList<>(); int numSimultaneousCalls = NUMBER_OF_REQUESTS; for (int i = 0; i < numSimultaneousCalls; i++) { futures.add(sendServerRequest(endpointUrl)); } // Wait for all the requests to return List<Map<String, String>> results = new ArrayList<>(); for (Future<Map<String, String>> f : futures) { results.add(f.get()); } // We need to sleep for a short time to give the metrics handler a chance to process the request before we start asserting on the metrics values. Thread.sleep(250); }
metricsListener.onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, state); .addListener((ChannelFutureListener) channelFuture -> { if (channelFuture.isSuccess()) metricsListener.onEvent(ServerMetricsEvent.RESPONSE_SENT, stateCopy); else { metricsListener.onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, null);
/** * Execute some code and upate the specified counter. This invocation increments the counter by 1 * * @param c * A Callable to execute * @param meterName * The name of the meter to update * * @return The result of processing */ default <V> V counted(Callable<V> c, String meterName) throws Exception { return counted(c, meterName, 1L); }
/** * Execute some code and update the specified event rate metric. This invocation represents a single event * * @param c * A Consumer to execute. aka a closure with one argument and no returned value * @param arg * The argument to the function * @param meterName * The meter to update */ default <T> void metered(Consumer<T> c, T arg, String meterName) { metered(c, arg, meterName, 1L); }
@Test public void channelRead_cleans_the_state_and_starts_metrics_request_and_removes_any_existing_IdleChannelTimeoutHandler() throws Exception { // when handler.channelRead(ctxMock, msgMockFirstChunkOnly); // then verify(stateMock).cleanStateForNewRequest(); verify(metricsListenerMock).onEvent(ServerMetricsEvent.REQUEST_RECEIVED, stateMock); verify(pipelineMock).get(IDLE_CHANNEL_TIMEOUT_HANDLER_NAME); verify(pipelineMock).remove(idleChannelTimeoutHandlerMock); }
/** * Execute some code and update the specified counter. This invocation increments the counter by 1 * * @param c * A Consumer to execute. aka a closure with one argument and no returned value * @param arg * The argument to the function * @param counterName * The name of the counter to update */ default <T> void counted(Consumer<T> c, T arg, String counterName) { counted(c, arg, counterName, 1L); }
/** * Execute some code and update the specified event rate metric. This invocation represents a single event * * @param c * a Callable to execute * @param meterName * The meter to update * * @return The result of processing */ default <V> V metered(Callable<V> c, String meterName) throws Exception { return metered(c, meterName, 1L); }
@Test public void finalizeChannelPipeline_should_send_error_response_if_state_indicates_no_response_already_sent() throws JsonProcessingException { // given state.setResponseWriterFinalChunkChannelFuture(null); HttpProcessingState stateSpy = spy(state); doReturn(stateSpy).when(stateAttributeMock).get(); doReturn(false).when(responseInfoMock).isResponseSendingStarted(); Object msg = new Object(); Throwable cause = new Exception("intentional test exception"); RequestInfo<?> requestInfoMock = mock(RequestInfo.class); ResponseInfo<ErrorResponseBody> errorResponseMock = mock(ResponseInfo.class); doReturn(requestInfoMock).when(exceptionHandlingHandlerMock).getRequestInfo(stateSpy, msg); doReturn(errorResponseMock).when(exceptionHandlingHandlerMock).processUnhandledError(eq(stateSpy), eq(msg), any(Throwable.class)); // when handler.finalizeChannelPipeline(ctxMock, msg, stateSpy, cause); // then verify(responseSenderMock).sendErrorResponse(ctxMock, requestInfoMock, errorResponseMock); verify(metricsListenerMock).onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, stateSpy); verify(ctxMock).flush(); }
/** * Execute some code and update the specified counter. This invocation increments the counter by 1 * * @param f * A Function to execute. aka a closure with one argument and a returned value * @param arg * The argument to the function * @param counterName * The name of the counter to update * * @return The result of processing */ default <T, R> R counted(Function<T, R> f, T arg, String counterName) { return counted(f, arg, counterName, 1L); }
/** * Execute some code and update the specified event rate metric. This invocation represents a single event * * @param f * A Function to execute. aka a closure with one argument and a returned value * @param arg * The argument to the function * @param meterName * The meter to update * * @return The result of processing */ default <T, R> R metered(Function<T, R> f, T arg, String meterName) { return metered(f, arg, meterName, 1L); }
@Test public void finalizeChannelPipeline_should_send_event_to_metricsListener_for_failure_response_and_flush_context() throws Exception { // given ChannelFuture responseWriterChannelFuture = mock(ChannelFuture.class); state.setResponseWriterFinalChunkChannelFuture(responseWriterChannelFuture); HttpProcessingState stateSpy = spy(state); doReturn(stateSpy).when(stateAttributeMock).get(); ChannelFuture responseWriteFutureResult = mock(ChannelFuture.class); doReturn(false).when(responseWriteFutureResult).isSuccess(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isFalse(); // when handler.finalizeChannelPipeline(ctxMock, null, stateSpy, null); // then ArgumentCaptor<GenericFutureListener> channelFutureListenerArgumentCaptor = ArgumentCaptor.forClass(GenericFutureListener.class); verify(responseWriterChannelFuture).addListener(channelFutureListenerArgumentCaptor.capture()); GenericFutureListener futureListener = channelFutureListenerArgumentCaptor.getValue(); assertThat(futureListener, notNullValue()); futureListener.operationComplete(responseWriteFutureResult); verify(metricsListenerMock).onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, null); verify(ctxMock).flush(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isTrue(); }
/** * Execute some code and update the specified counter. The invocation increments the counter by 1 * * @param bc * A BiConsumer to execute. aka a closure with two arguments and no returned value * @param arg1 * The first argument * @param arg2 * The second argument * @param counterName * The name of the counter to update */ default <T, U> void counted(BiConsumer<T, U> bc, T arg1, U arg2, String counterName) { counted(bc, arg1, arg2, counterName, 1L); }
/** * Execute some code and update the specified event rate metric. This invocation represents a single event * * @param bc * A BiConsumer to execute. aka a closure with two arguments and no returned value * @param arg1 * The first argument * @param arg2 * the second argument * @param meterName * The meter to update */ default <T, U> void metered(BiConsumer<T, U> bc, T arg1, U arg2, String meterName) { metered(bc, arg1, arg2, meterName, 1L); }
/** * Execute some code and update the specified counter. This invocation increments the counter by 1 * * @param bf * A BiFunction to execute. aka a closure with two arguments and one returned value * @param arg1 * The first argument * @param arg2 * The second argument * @param counterName * The name of the counter to update * * @return The result of processing */ default <T, U, R> R counted(BiFunction<T, U, R> bf, T arg1, U arg2, String counterName) { return counted(bf, arg1, arg2, counterName, 1L); }
/** * Execute some code and update the specified event rate metric. This invocation represents a single event * * @param bf * A BiFunction to execute. aka a closure with two arguments and one returned value * @param arg1 * The first argument * @param arg2 * The second argument * @param meterName * The meter to update */ default <T, U, R> R metered(BiFunction<T, U, R> bf, T arg1, U arg2, String meterName) { return metered(bf, arg1, arg2, meterName, 1L); }