2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.impl.statistics;
10 import com.google.common.util.concurrent.AbstractScheduledService;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import com.google.common.util.concurrent.Service;
16 import com.google.common.util.concurrent.SettableFuture;
17 import java.util.concurrent.CancellationException;
18 import java.util.concurrent.CompletableFuture;
19 import java.util.concurrent.TimeUnit;
20 import java.util.function.Supplier;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.opendaylight.openflowplugin.api.ConnectionException;
24 public class StatisticsPollingService extends AbstractScheduledService {
25 private static final long DEFAULT_STATS_TIMEOUT = 50000;
27 private final TimeCounter counter;
28 private final long pollingInterval;
29 private final long maximumTimerDelay;
30 private final Supplier<ListenableFuture<Boolean>> gatheringSupplier;
31 private final SettableFuture<Void> future = SettableFuture.create();
33 StatisticsPollingService(@NonNull final TimeCounter counter,
34 final long pollingInterval,
35 final long maximumTimerDelay,
36 @NonNull final Supplier<ListenableFuture<Boolean>> gatheringSupplier) {
37 this.counter = counter;
38 this.pollingInterval = pollingInterval;
39 this.maximumTimerDelay = maximumTimerDelay;
40 this.gatheringSupplier = gatheringSupplier;
41 this.addListener(new StatisticsPollingServiceListener(), MoreExecutors.directExecutor());
44 ListenableFuture<Void> stop() {
50 protected void startUp() {
55 protected void runOneIteration() throws Exception {
56 final long averageTime = counter.getAverageTimeBetweenMarks();
57 final long statsTimeout = averageTime > 0 ? 3 * averageTime : DEFAULT_STATS_TIMEOUT;
58 final CompletableFuture<Boolean> waitFuture = new CompletableFuture<>();
60 Futures.addCallback(gatheringSupplier.get(), new FutureCallback<Boolean>() {
62 public void onSuccess(final Boolean result) {
63 waitFuture.complete(result);
67 public void onFailure(final Throwable throwable) {
68 waitFuture.completeExceptionally(throwable);
70 }, MoreExecutors.directExecutor());
73 waitFuture.get(statsTimeout, TimeUnit.MILLISECONDS);
75 counter.addTimeMark();
80 protected Scheduler scheduler() {
81 final long averageStatisticsGatheringTime = counter.getAverageTimeBetweenMarks();
82 long currentTimerDelay = pollingInterval;
84 if (averageStatisticsGatheringTime > currentTimerDelay) {
85 currentTimerDelay = averageStatisticsGatheringTime;
87 if (currentTimerDelay > maximumTimerDelay) {
88 currentTimerDelay = maximumTimerDelay;
92 return Scheduler.newFixedDelaySchedule(currentTimerDelay, currentTimerDelay, TimeUnit.MILLISECONDS);
95 private final class StatisticsPollingServiceListener extends Service.Listener {
97 public void terminated(final Service.State from) {
98 super.terminated(from);
103 public void failed(final Service.State from, final Throwable failure) {
104 super.failed(from, failure);
105 if (!(failure instanceof CancellationException) && !(failure instanceof ConnectionException)) {
106 future.setException(failure);