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 javax.annotation.Nonnull;
22 import javax.annotation.Nullable;
23 import org.opendaylight.openflowplugin.api.ConnectionException;
25 public class StatisticsPollingService extends AbstractScheduledService {
26 private static final long DEFAULT_STATS_TIMEOUT = 50000;
28 private final TimeCounter counter;
29 private final long pollingInterval;
30 private final long maximumTimerDelay;
31 private final Supplier<ListenableFuture<Boolean>> gatheringSupplier;
32 private final SettableFuture<Void> future = SettableFuture.create();
34 StatisticsPollingService(@Nonnull final TimeCounter counter,
35 final long pollingInterval,
36 final long maximumTimerDelay,
37 @Nonnull final Supplier<ListenableFuture<Boolean>> gatheringSupplier) {
38 this.counter = counter;
39 this.pollingInterval = pollingInterval;
40 this.maximumTimerDelay = maximumTimerDelay;
41 this.gatheringSupplier = gatheringSupplier;
42 this.addListener(new StatisticsPollingServiceListener(), MoreExecutors.directExecutor());
45 ListenableFuture<Void> stop() {
51 protected void startUp() throws Exception {
56 protected void runOneIteration() throws Exception {
57 final long averageTime = counter.getAverageTimeBetweenMarks();
58 final long statsTimeout = averageTime > 0 ? 3 * averageTime : DEFAULT_STATS_TIMEOUT;
59 final CompletableFuture<Boolean> waitFuture = new CompletableFuture<>();
61 Futures.addCallback(gatheringSupplier.get(), new FutureCallback<Boolean>() {
63 public void onSuccess(@Nullable final Boolean result) {
64 waitFuture.complete(result);
68 public void onFailure(@Nonnull final Throwable throwable) {
69 waitFuture.completeExceptionally(throwable);
71 }, MoreExecutors.directExecutor());
74 waitFuture.get(statsTimeout, TimeUnit.MILLISECONDS);
76 counter.addTimeMark();
81 protected Scheduler scheduler() {
82 final long averageStatisticsGatheringTime = counter.getAverageTimeBetweenMarks();
83 long currentTimerDelay = pollingInterval;
85 if (averageStatisticsGatheringTime > currentTimerDelay) {
86 currentTimerDelay = averageStatisticsGatheringTime;
88 if (currentTimerDelay > maximumTimerDelay) {
89 currentTimerDelay = maximumTimerDelay;
93 return Scheduler.newFixedDelaySchedule(currentTimerDelay, currentTimerDelay, TimeUnit.MILLISECONDS);
96 private final class StatisticsPollingServiceListener extends Service.Listener {
98 public void terminated(final Service.State from) {
99 super.terminated(from);
104 public void failed(final Service.State from, final Throwable failure) {
105 super.failed(from, failure);
106 if (!(failure instanceof CancellationException) && !(failure instanceof ConnectionException)) {
107 future.setException(failure);