View Javadoc
1   /*
2    * Copyright 2014 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.handler.traffic;
17  
18  import io.netty5.handler.traffic.GlobalChannelTrafficShapingHandler.PerChannel;
19  import io.netty5.util.concurrent.EventExecutorGroup;
20  
21  import java.util.concurrent.TimeUnit;
22  
23  import static io.netty5.util.internal.ObjectUtil.checkNotNullWithIAE;
24  
25  /**
26   * Version for {@link GlobalChannelTrafficShapingHandler}.
27   * This TrafficCounter is the Global one, and its special property is to directly handle
28   * other channel's TrafficCounters. In particular, there are no scheduler for those
29   * channel's TrafficCounters because it is managed by this one.
30   */
31  public class GlobalChannelTrafficCounter extends TrafficCounter {
32      /**
33       * @param trafficShapingHandler the associated {@link GlobalChannelTrafficShapingHandler}.
34       * @param executor the underlying executor service for scheduling checks (both Global and per Channel).
35       * @param name the name given to this monitor.
36       * @param checkInterval the checkInterval in millisecond between two computations.
37       */
38      public GlobalChannelTrafficCounter(GlobalChannelTrafficShapingHandler trafficShapingHandler,
39                                         EventExecutorGroup executor, String name, long checkInterval) {
40          super(trafficShapingHandler, executor, name, checkInterval);
41          checkNotNullWithIAE(executor, "executor");
42      }
43  
44      /**
45       * Class to implement monitoring at fix delay.
46       * This version is Mixed in the way it mixes Global and Channel counters.
47       */
48      private static class MixedTrafficMonitoringTask implements Runnable {
49          /**
50           * The associated TrafficShapingHandler
51           */
52          private final GlobalChannelTrafficShapingHandler trafficShapingHandler1;
53  
54          /**
55           * The associated TrafficCounter
56           */
57          private final TrafficCounter counter;
58  
59          /**
60           * @param trafficShapingHandler The parent handler to which this task needs to callback to for accounting.
61           * @param counter The parent TrafficCounter that we need to reset the statistics for.
62           */
63          MixedTrafficMonitoringTask(
64                  GlobalChannelTrafficShapingHandler trafficShapingHandler,
65                  TrafficCounter counter) {
66              trafficShapingHandler1 = trafficShapingHandler;
67              this.counter = counter;
68          }
69  
70          @Override
71          public void run() {
72              if (!counter.monitorActive) {
73                  return;
74              }
75              long newLastTime = milliSecondFromNano();
76              counter.resetAccounting(newLastTime);
77              for (PerChannel perChannel : trafficShapingHandler1.channelQueues.values()) {
78                  perChannel.channelTrafficCounter.resetAccounting(newLastTime);
79              }
80              trafficShapingHandler1.doAccounting(counter);
81          }
82      }
83  
84      /**
85       * Start the monitoring process.
86       */
87      @Override
88      public synchronized void start() {
89          if (monitorActive) {
90              return;
91          }
92          lastTime.set(milliSecondFromNano());
93          long localCheckInterval = checkInterval.get();
94          if (localCheckInterval > 0) {
95              monitorActive = true;
96              monitor = new MixedTrafficMonitoringTask((GlobalChannelTrafficShapingHandler) trafficShapingHandler, this);
97              scheduledFuture =
98                  executor.scheduleAtFixedRate(monitor, 0, localCheckInterval, TimeUnit.MILLISECONDS);
99          }
100     }
101 
102     /**
103      * Stop the monitoring process.
104      */
105     @Override
106     public synchronized void stop() {
107         if (!monitorActive) {
108             return;
109         }
110         monitorActive = false;
111         resetAccounting(milliSecondFromNano());
112         trafficShapingHandler.doAccounting(this);
113         if (scheduledFuture != null) {
114             scheduledFuture.cancel();
115         }
116     }
117 
118     @Override
119     public void resetCumulativeTime() {
120         for (PerChannel perChannel :
121             ((GlobalChannelTrafficShapingHandler) trafficShapingHandler).channelQueues.values()) {
122             perChannel.channelTrafficCounter.resetCumulativeTime();
123         }
124         super.resetCumulativeTime();
125     }
126 
127 }