use of io.mantisrx.common.metrics.Counter in project mantis by Netflix.
the class SseWorkerConnectionTest method testStreamContentDrops.
@Test
public void testStreamContentDrops() throws Exception {
SpectatorRegistryFactory.setRegistry(new DefaultRegistry());
String metricGroupString = "testmetric";
MetricGroupId metricGroupId = new MetricGroupId(metricGroupString);
SseWorkerConnection workerConnection = new SseWorkerConnection("connection_type", "hostname", 80, b -> {
}, b -> {
}, t -> {
}, 600, false, new CopyOnWriteArraySet<>(), 1, null, true, metricGroupId);
HttpClientResponse<ServerSentEvent> response = mock(HttpClientResponse.class);
TestScheduler testScheduler = Schedulers.test();
// Events are just "0", "1", "2", ...
Observable<ServerSentEvent> contentObs = Observable.interval(1, TimeUnit.SECONDS, testScheduler).map(t -> new ServerSentEvent(Unpooled.copiedBuffer(Long.toString(t), Charset.defaultCharset())));
when(response.getContent()).thenReturn(contentObs);
TestSubscriber<MantisServerSentEvent> subscriber = new TestSubscriber<>(1);
workerConnection.streamContent(response, b -> {
}, 600, "delimiter").subscribeOn(testScheduler).subscribe(subscriber);
testScheduler.advanceTimeBy(100, TimeUnit.SECONDS);
subscriber.assertValueCount(1);
List<MantisServerSentEvent> events = subscriber.getOnNextEvents();
assertEquals("0", events.get(0).getEventAsString());
Metrics metrics = MetricsRegistry.getInstance().getMetric(metricGroupId);
Counter onNextCounter = metrics.getCounter(DropOperator.Counters.onNext.toString());
Counter droppedCounter = metrics.getCounter(DropOperator.Counters.dropped.toString());
logger.info("next: {}", onNextCounter.value());
logger.info("drop: {}", droppedCounter.value());
assertTrue(onNextCounter.value() < 10);
assertTrue(droppedCounter.value() > 90);
}
use of io.mantisrx.common.metrics.Counter in project mantis by Netflix.
the class PushServerSse method createServer.
@Override
public RxServer<?, ?> createServer() {
RxServer<HttpServerRequest<String>, HttpServerResponse<ServerSentEvent>> server = RxNetty.newHttpServerBuilder(port, new RequestHandler<String, ServerSentEvent>() {
@Override
public Observable<Void> handle(HttpServerRequest<String> request, final HttpServerResponse<ServerSentEvent> response) {
final Map<String, List<String>> queryParameters = request.getQueryParameters();
final Counter sseProcessedCounter;
final Counter sseDroppedCounter;
// heartbeat state
boolean enableHeartbeats = false;
boolean enableBinaryOutput = false;
final AtomicLong heartBeatReadIdleSec = new AtomicLong(2);
SerializedSubject<String, String> metaMsgSubject = PublishSubject.<String>create().toSerialized();
final AtomicLong metaMessagesFreqMSec = new AtomicLong(1000);
boolean enableMetaMessages = false;
final AtomicLong lastWriteTime = new AtomicLong();
Subscription heartbeatSubscription = null;
Subscription metaMsgSubscription = null;
// sample state
boolean enableSampling = false;
long samplingTimeMsec = 0;
// client state
String groupId = null;
String slotId = null;
String id = null;
Func1<T, Boolean> predicateFunction = null;
if (predicate != null) {
predicateFunction = predicate.call(queryParameters);
}
byte[] delimiter = CompressionUtils.MANTIS_SSE_DELIMITER_BINARY;
if (queryParameters != null && !queryParameters.isEmpty()) {
if (queryParameters.containsKey(MantisSSEConstants.ID)) {
id = queryParameters.get(MantisSSEConstants.ID).get(0);
}
if (queryParameters.containsKey(MantisSSEConstants.SLOT_ID)) {
slotId = queryParameters.get(MantisSSEConstants.SLOT_ID).get(0);
}
// support groupId and clientId for grouping
if (queryParameters.containsKey(MantisSSEConstants.GROUP_ID)) {
groupId = queryParameters.get(MantisSSEConstants.GROUP_ID).get(0);
}
if (queryParameters.containsKey(MantisSSEConstants.CLIENT_ID)) {
groupId = queryParameters.get(MantisSSEConstants.CLIENT_ID).get(0);
}
if (queryParameters.containsKey(MantisSSEConstants.HEARTBEAT_SEC)) {
heartBeatReadIdleSec.set(Long.parseLong(queryParameters.get(MantisSSEConstants.HEARTBEAT_SEC).get(0)));
if (heartBeatReadIdleSec.get() < 1) {
throw new IllegalArgumentException("Sampling rate too low: " + samplingTimeMsec);
}
enableHeartbeats = true;
}
if (queryParameters != null && queryParameters.containsKey(MantisSSEConstants.MANTIS_ENABLE_COMPRESSION)) {
String enableBinaryOutputStr = queryParameters.get(MantisSSEConstants.MANTIS_ENABLE_COMPRESSION).get(0);
if ("true".equalsIgnoreCase(enableBinaryOutputStr)) {
logger.info("Binary compression requested");
enableBinaryOutput = true;
}
}
if (queryParameters.containsKey(MantisSSEConstants.ENABLE_PINGS)) {
String enablePings = queryParameters.get(MantisSSEConstants.ENABLE_PINGS).get(0);
if ("true".equalsIgnoreCase(enablePings)) {
enableHeartbeats = true;
}
}
if (queryParameters.containsKey(MantisSSEConstants.ENABLE_META_MESSAGES)) {
String enableMetaMessagesStr = queryParameters.get(MantisSSEConstants.ENABLE_META_MESSAGES).get(0);
if ("true".equalsIgnoreCase(enableMetaMessagesStr)) {
enableMetaMessages = true;
}
}
if (queryParameters.containsKey(MantisSSEConstants.META_MESSAGES_SEC)) {
metaMessagesFreqMSec.set(Long.parseLong(queryParameters.get(MantisSSEConstants.META_MESSAGES_SEC).get(0)));
if (metaMessagesFreqMSec.get() < 250) {
throw new IllegalArgumentException("Meta message frequence rate too low: " + metaMessagesFreqMSec.get());
}
enableMetaMessages = true;
}
if (queryParameters.containsKey(MantisSSEConstants.SAMPLE)) {
samplingTimeMsec = Long.parseLong(queryParameters.get(MantisSSEConstants.SAMPLE).get(0)) * 1000;
if (samplingTimeMsec < 50) {
throw new IllegalArgumentException("Sampling rate too low: " + samplingTimeMsec);
}
enableSampling = true;
}
if (queryParameters.containsKey(MantisSSEConstants.SAMPLE_M_SEC)) {
samplingTimeMsec = Long.parseLong(queryParameters.get(MantisSSEConstants.SAMPLE_M_SEC).get(0));
if (samplingTimeMsec < 50) {
throw new IllegalArgumentException("Sampling rate too low: " + samplingTimeMsec);
}
enableSampling = true;
}
if (queryParameters.containsKey(MantisSSEConstants.MANTIS_COMPRESSION_DELIMITER)) {
String rawDelimiter = queryParameters.get(MantisSSEConstants.MANTIS_COMPRESSION_DELIMITER).get(0);
if (rawDelimiter != null && !rawDelimiter.isEmpty()) {
delimiter = rawDelimiter.getBytes();
}
}
if (queryParameters.containsKey(MantisSSEConstants.MQL)) {
String query = queryParameters.get(MantisSSEConstants.MQL).get(0);
if ((Boolean) mqlParses.invoke(query)) {
Query q = (Query) mqlMakeQuery.invoke(groupId, query);
predicateFunction = (T datum) -> datum instanceof Map ? q.matches((Map) datum) : true;
}
}
}
InetSocketAddress socketAddress = (InetSocketAddress) response.getChannel().remoteAddress();
Metrics metrics;
if (groupId == null) {
String address = socketAddress.getAddress().toString();
metrics = registerSseMetrics(address, address);
} else {
metrics = registerSseMetrics(groupId, socketAddress.getAddress().toString());
}
sseProcessedCounter = metrics.getCounter(PROCESSED_COUNTER_METRIC_NAME);
sseDroppedCounter = metrics.getCounter(DROPPED_COUNTER_METRIC_NAME);
response.getHeaders().set("Access-Control-Allow-Origin", "*");
response.getHeaders().set("content-type", "text/event-stream");
response.getHeaders().set("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
response.getHeaders().set("Pragma", "no-cache");
response.flush();
if (queryParameters != null && requestPreprocessor != null) {
requestPreprocessor.call(queryParameters, processorState);
}
if (enableMetaMessages && metaMessagesFreqMSec.get() > 0) {
logger.info("Enabling Meta messages, interval : " + metaMessagesFreqMSec.get() + " ms");
metaMsgSubscription = metaMsgSubject.throttleLast(metaMessagesFreqMSec.get(), TimeUnit.MILLISECONDS).doOnNext((String t) -> {
if (t != null && !t.isEmpty()) {
long currentTime = System.currentTimeMillis();
ByteBuf data = response.getAllocator().buffer().writeBytes(t.getBytes());
response.writeAndFlush(new ServerSentEvent(data));
lastWriteTime.set(currentTime);
}
}).subscribe();
}
if (enableHeartbeats && heartBeatReadIdleSec.get() > 0) {
logger.info("Enabling hearts, interval: " + heartBeatReadIdleSec);
heartbeatSubscription = Observable.interval(2, heartBeatReadIdleSec.get(), TimeUnit.SECONDS).doOnNext((Long t1) -> {
long currentTime = System.currentTimeMillis();
long diff = (currentTime - lastWriteTime.get()) / 1000;
if (diff > heartBeatReadIdleSec.get()) {
ByteBuf data = response.getAllocator().buffer().writeBytes("ping".getBytes());
response.writeAndFlush(new ServerSentEvent(data));
lastWriteTime.set(currentTime);
}
}).subscribe();
}
Action0 connectionClosedCallback = null;
if (queryParameters != null && requestPostprocessor != null) {
connectionClosedCallback = new Action0() {
@Override
public void call() {
requestPostprocessor.call(queryParameters, processorState);
}
};
}
class SubscribeCallback implements Action0 {
@Override
public void call() {
if (queryParameters != null && subscribeProcessor != null) {
subscribeProcessor.call(queryParameters, processorState);
}
}
}
return manageConnectionWithCompression(response, socketAddress.getHostString(), socketAddress.getPort(), groupId, slotId, id, lastWriteTime, enableHeartbeats, heartbeatSubscription, enableSampling, samplingTimeMsec, metaMsgSubject, metaMsgSubscription, predicateFunction, connectionClosedCallback, sseProcessedCounter, sseDroppedCounter, new SubscribeCallback(), enableBinaryOutput, true, delimiter);
}
}).pipelineConfigurator(PipelineConfigurators.serveSseConfigurator()).channelOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 5 * 1024 * 1024)).build();
return server;
}
use of io.mantisrx.common.metrics.Counter in project mantis by Netflix.
the class ServerSentEventRequestHandler method handle.
@Override
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, final HttpServerResponse<ServerSentEvent> response) {
InetSocketAddress socketAddress = (InetSocketAddress) response.getChannel().remoteAddress();
LOG.info("HTTP SSE connection received from " + socketAddress.getAddress() + ":" + socketAddress.getPort() + " queryParams: " + request.getQueryParameters());
final String socketAddrStr = socketAddress.getAddress().toString();
final WritableEndpoint<String> sn = new WritableEndpoint<>(socketAddress.getHostString(), socketAddress.getPort(), Endpoint.uniqueHost(socketAddress.getHostString(), socketAddress.getPort(), null));
final Map<String, List<String>> queryParameters = request.getQueryParameters();
final SlotAssignmentManager<String> slotMgr = ssm.registerServer(sn, queryParameters);
final AtomicLong lastResponseFlush = new AtomicLong();
lastResponseFlush.set(-1);
final AtomicLong lastResponseSent = new AtomicLong(-1);
// copy reference, then apply request specific filters, sampling
Observable<T> requestObservable = observableToServe;
// decouple the observable on a separate thread and add backpressure handling
// ServiceRegistry.INSTANCE.getPropertiesService().getStringValue("sse.decouple", "false");
String decoupleSSE = "false";
if ("true".equals(decoupleSSE)) {
final BasicTag sockAddrTag = new BasicTag("sockAddr", Optional.ofNullable(socketAddrStr).orElse("none"));
requestObservable = requestObservable.lift(new DropOperator<T>("outgoing_ServerSentEventRequestHandler", sockAddrTag)).observeOn(Schedulers.io());
}
response.getHeaders().set("Access-Control-Allow-Origin", "*");
response.getHeaders().set("content-type", "text/event-stream");
response.getHeaders().set("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
response.getHeaders().set("Pragma", "no-cache");
response.flush();
String uniqueClientId = socketAddrStr;
if (queryParameters != null && queryParameters.containsKey(CLIENT_ID_PARAM)) {
// enablePings
uniqueClientId = queryParameters.get(CLIENT_ID_PARAM).get(0);
}
if (queryParameters != null && queryParameters.containsKey(FORMAT_PARAM)) {
format = queryParameters.get(FORMAT_PARAM).get(0);
}
if (queryParameters != null && requestPreprocessor != null) {
requestPreprocessor.call(queryParameters, context);
}
// apply sampling, milli, then seconds
if (queryParameters != null && queryParameters.containsKey(SAMPLE_PARAM_MSEC)) {
// apply sampling rate
int samplingRate = Integer.parseInt(queryParameters.get(SAMPLE_PARAM_MSEC).get(0));
requestObservable = requestObservable.sample(samplingRate, TimeUnit.MILLISECONDS);
}
if (queryParameters != null && queryParameters.containsKey(SAMPLE_PARAM)) {
// apply sampling rate
int samplingRate = Integer.parseInt(queryParameters.get(SAMPLE_PARAM).get(0));
requestObservable = requestObservable.sample(samplingRate, TimeUnit.SECONDS);
}
if (queryParameters != null && queryParameters.containsKey(ENABLE_PINGS_PARAM)) {
// enablePings
String enablePings = queryParameters.get(ENABLE_PINGS_PARAM).get(0);
if ("true".equalsIgnoreCase(enablePings)) {
pingsEnabled = true;
} else {
pingsEnabled = false;
}
}
if (queryParameters != null && queryParameters.containsKey("delay")) {
// apply flush
try {
int flushInterval = Integer.parseInt(queryParameters.get("delay").get(0));
if (flushInterval >= 50) {
flushIntervalMillis = flushInterval;
} else {
LOG.warn("delay parameter too small " + flushInterval + " min. is 100");
}
} catch (Exception e) {
e.printStackTrace();
}
}
final byte[] delimiter = queryParameters != null && queryParameters.containsKey(MantisSSEConstants.MANTIS_COMPRESSION_DELIMITER) && queryParameters.get(MantisSSEConstants.MANTIS_COMPRESSION_DELIMITER).get(0) != null ? queryParameters.get(MantisSSEConstants.MANTIS_COMPRESSION_DELIMITER).get(0).getBytes() : null;
Tag[] tags = new Tag[2];
final String clientId = Optional.ofNullable(uniqueClientId).orElse("none");
final String sockAddr = Optional.ofNullable(socketAddrStr).orElse("none");
tags[0] = new BasicTag("clientId", clientId);
tags[1] = new BasicTag("sockAddr", sockAddr);
Metrics sseSinkMetrics = new Metrics.Builder().id("ServerSentEventRequestHandler", tags).addCounter("processedCounter").addCounter("pingCounter").addCounter("errorCounter").addCounter("droppedCounter").addCounter("flushCounter").build();
final Counter msgProcessedCounter = sseSinkMetrics.getCounter("processedCounter");
final Counter pingCounter = sseSinkMetrics.getCounter("pingCounter");
final Counter errorCounter = sseSinkMetrics.getCounter("errorCounter");
final Counter droppedWrites = sseSinkMetrics.getCounter("droppedCounter");
final Counter flushCounter = sseSinkMetrics.getCounter("flushCounter");
// get predicate, defaults to return true for all T
Func1<T, Boolean> filterFunction = new Func1<T, Boolean>() {
@Override
public Boolean call(T t1) {
return true;
}
};
if (queryParameters != null && predicate != null) {
filterFunction = predicate.getPredicate().call(queryParameters);
}
final Subscription timerSubscription = Observable.interval(1, TimeUnit.SECONDS).doOnNext(new Action1<Long>() {
@Override
public void call(Long t1) {
long currentTime = System.currentTimeMillis();
if (pingsEnabled && (lastResponseSent.get() == -1 || currentTime > lastResponseSent.get() + PING_INTERVAL)) {
pingCounter.increment();
response.writeStringAndFlush(PING);
lastResponseSent.set(currentTime);
}
}
}).subscribe();
return requestObservable.filter(filterFunction).map(encoder).lift(new DisableBackPressureOperator<String>()).buffer(flushIntervalMillis, TimeUnit.MILLISECONDS).flatMap(new Func1<List<String>, Observable<Void>>() {
@Override
public Observable<Void> call(List<String> valueList) {
if (response.isCloseIssued() || !response.getChannel().isActive()) {
LOG.info("Client closed detected, throwing closed channel exception");
return Observable.error(new ClosedChannelException());
}
List<String> filteredList = valueList.stream().filter(e -> {
return slotMgr.filter(sn, e.getBytes());
}).collect(Collectors.toList());
if (response.getChannel().isWritable()) {
flushCounter.increment();
if (format.equals(BINARY_FORMAT)) {
boolean useSnappy = true;
try {
String compressedList = delimiter == null ? CompressionUtils.compressAndBase64Encode(filteredList, useSnappy) : CompressionUtils.compressAndBase64Encode(filteredList, useSnappy, delimiter);
StringBuilder sb = new StringBuilder(3);
sb.append(SSE_DATA_PREFIX);
sb.append(compressedList);
sb.append(TWO_NEWLINES);
msgProcessedCounter.increment(valueList.size());
lastResponseSent.set(System.currentTimeMillis());
return response.writeStringAndFlush(sb.toString());
} catch (Exception e) {
LOG.warn("Could not compress data" + e.getMessage());
droppedWrites.increment(valueList.size());
return Observable.empty();
}
} else {
int noOfMsgs = 0;
StringBuilder sb = new StringBuilder(valueList.size() * 3);
for (String s : filteredList) {
sb.append(SSE_DATA_PREFIX);
sb.append(s);
sb.append(TWO_NEWLINES);
noOfMsgs++;
}
msgProcessedCounter.increment(noOfMsgs);
lastResponseSent.set(System.currentTimeMillis());
return response.writeStringAndFlush(sb.toString());
}
} else {
//
droppedWrites.increment(filteredList.size());
}
return Observable.empty();
}
}).onErrorResumeNext(new Func1<Throwable, Observable<? extends Void>>() {
@Override
public Observable<? extends Void> call(Throwable throwable) {
Throwable cause = throwable.getCause();
// ignore closed channel exceptions, this is
// when the connection was closed on the client
// side without informing the server
errorCounter.increment();
if (cause != null && !(cause instanceof ClosedChannelException)) {
LOG.warn("Error detected in SSE sink", cause);
if (errorEncoder != null) {
// write error out on connection
// response.writeAndFlush(errorEncoder.call(throwable));
ByteBuf errType = response.getAllocator().buffer().writeBytes("error: ".getBytes());
ByteBuf errRes = response.getAllocator().buffer().writeBytes((errorEncoder.call(throwable)).getBytes());
response.writeAndFlush(ServerSentEvent.withEventType(errType, errRes));
}
throwable.printStackTrace();
}
if (requestPostprocessor != null && queryParameters != null) {
requestPostprocessor.call(queryParameters, context);
}
ssm.deregisterServer(sn, queryParameters);
timerSubscription.unsubscribe();
return Observable.error(throwable);
}
});
}
use of io.mantisrx.common.metrics.Counter in project mantis by Netflix.
the class LegacyTcpPushServer method createServer.
@Override
public RxServer<?, ?> createServer() {
RxServer<RemoteRxEvent, RemoteRxEvent> server = RxNetty.newTcpServerBuilder(port, new ConnectionHandler<RemoteRxEvent, RemoteRxEvent>() {
@Override
public Observable<Void> handle(final ObservableConnection<RemoteRxEvent, RemoteRxEvent> newConnection) {
final InetSocketAddress socketAddress = (InetSocketAddress) newConnection.getChannel().remoteAddress();
// extract groupId, id, predicate from incoming byte[]
return newConnection.getInput().flatMap(new Func1<RemoteRxEvent, Observable<Void>>() {
@Override
public Observable<Void> call(RemoteRxEvent incomingRequest) {
if (incomingRequest.getType() == RemoteRxEvent.Type.subscribed) {
Map<String, String> params = incomingRequest.getSubscribeParameters();
// client state
String id = null;
String slotId = null;
String groupId = null;
// sample state
boolean enableSampling = false;
long samplingTimeMsec = 0;
// predicate state
Map<String, List<String>> predicateParams = null;
if (params != null && !params.isEmpty()) {
predicateParams = new HashMap<String, List<String>>();
for (Entry<String, String> entry : params.entrySet()) {
List<String> values = new LinkedList<>();
values.add(entry.getValue());
predicateParams.put(entry.getKey(), values);
}
if (params.containsKey("id")) {
id = params.get("id");
}
if (params.containsKey("slotId")) {
slotId = params.get("slotId");
}
if (params.containsKey("groupId")) {
groupId = params.get("groupId");
}
if (params.containsKey("sample")) {
samplingTimeMsec = Long.parseLong(params.get("sample")) * 1000;
if (samplingTimeMsec < 50) {
throw new IllegalArgumentException("Sampling rate too low: " + samplingTimeMsec);
}
enableSampling = true;
}
if (params.containsKey("sampleMSec")) {
samplingTimeMsec = Long.parseLong(params.get("sampleMSec"));
if (samplingTimeMsec < 50) {
throw new IllegalArgumentException("Sampling rate too low: " + samplingTimeMsec);
}
enableSampling = true;
}
}
Func1<T, Boolean> predicateFunction = null;
if (predicate != null) {
predicateFunction = predicate.call(predicateParams);
}
// support legacy metrics per connection
Metrics sseSinkMetrics = new Metrics.Builder().name("DropOperator_outgoing_subject_" + slotId).addCounter("onNext").addCounter("dropped").build();
sseSinkMetrics = metricsRegistry.registerAndGet(sseSinkMetrics);
Counter legacyMsgProcessedCounter = sseSinkMetrics.getCounter("onNext");
Counter legacyDroppedWrites = sseSinkMetrics.getCounter("dropped");
return manageConnection(newConnection, socketAddress.getHostString(), socketAddress.getPort(), groupId, slotId, id, null, false, null, enableSampling, samplingTimeMsec, predicateFunction, null, legacyMsgProcessedCounter, legacyDroppedWrites, null);
}
return null;
}
});
}
}).pipelineConfigurator(new PipelineConfiguratorComposite<RemoteRxEvent, RemoteRxEvent>(new PipelineConfigurator<RemoteRxEvent, RemoteRxEvent>() {
@Override
public void configureNewPipeline(ChannelPipeline pipeline) {
// pipeline.addLast(new LoggingHandler(LogLevel.ERROR)); // uncomment to enable debug logging
pipeline.addLast("idleStateHandler", new IdleStateHandler(10, 2, 0));
pipeline.addLast("heartbeat", new HeartbeatHandler());
pipeline.addLast("gzipInflater", new JdkZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast("gzipDeflater", new JdkZlibDecoder(ZlibWrapper.GZIP));
// 4 bytes to encode length
pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
// max frame = half MB
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(5242880, 0, 4, 0, 4));
}
}, new LegacyTcpPipelineConfigurator(name))).channelOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 5 * 1024 * 1024)).build();
return server;
}
use of io.mantisrx.common.metrics.Counter in project mantis by Netflix.
the class SseWorkerConnection method hasDataDrop.
private boolean hasDataDrop() {
final Collection<Metrics> metrics = MetricsRegistry.getInstance().getMetrics(metricNamePrefix);
long totalDataDrop = 0L;
if (metrics != null && !metrics.isEmpty()) {
// logger.info("Got " + metrics.size() + " metrics for DropOperator");
for (Metrics m : metrics) {
final Counter dropped = m.getCounter("" + DropOperator.Counters.dropped);
final Counter onNext = m.getCounter("" + DropOperator.Counters.onNext);
if (dropped != null)
totalDataDrop += dropped.value();
}
}
if (totalDataDrop > lastDataDropValue) {
lastDataDropValue = totalDataDrop;
return true;
}
return false;
}
Aggregations