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    *   http://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 org.jboss.netty.handler.traffic;
17  
18  import org.jboss.netty.handler.traffic.GlobalChannelTrafficShapingHandler.PerChannel;
19  import org.jboss.netty.util.Timeout;
20  import org.jboss.netty.util.Timer;
21  import org.jboss.netty.util.TimerTask;
22  
23  import java.util.concurrent.TimeUnit;
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 name the name given to this monitor
35       * @param checkInterval the checkInterval in millisecond between two computations.
36       */
37      public GlobalChannelTrafficCounter(GlobalChannelTrafficShapingHandler trafficShapingHandler,
38              Timer timer, String name, long checkInterval) {
39          super(trafficShapingHandler, timer, name, checkInterval);
40          if (timer == null) {
41              throw new IllegalArgumentException("Timer must not be null");
42          }
43      }
44  
45      /**
46       * Class to implement monitoring at fix delay.
47       * This version is Mixed in the way it mixes Global and Channel counters.
48       */
49      private static final class MixedTrafficMonitoringTask implements TimerTask {
50          /**
51           * The associated TrafficShapingHandler
52           */
53          private final GlobalChannelTrafficShapingHandler trafficShapingHandler1;
54  
55          /**
56           * The associated TrafficCounter
57           */
58          private final TrafficCounter counter;
59  
60          /**
61           * @param trafficShapingHandler The parent handler to which this task needs to callback to for accounting.
62           * @param counter The parent TrafficCounter that we need to reset the statistics for.
63           */
64          MixedTrafficMonitoringTask(
65                  GlobalChannelTrafficShapingHandler trafficShapingHandler,
66                  TrafficCounter counter) {
67              trafficShapingHandler1 = trafficShapingHandler;
68              this.counter = counter;
69          }
70  
71          public void run(Timeout timeout) throws Exception {
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              counter.timer.newTimeout(this, counter.checkInterval.get(), TimeUnit.MILLISECONDS);
82          }
83      }
84  
85      /**
86       * Start the monitoring process.
87       */
88      @Override
89      public synchronized void start() {
90          if (monitorActive) {
91              return;
92          }
93          lastTime.set(milliSecondFromNano());
94          long localCheckInterval = checkInterval.get();
95          if (localCheckInterval > 0) {
96              monitorActive = true;
97              timerTask =
98                      new MixedTrafficMonitoringTask(
99                              (GlobalChannelTrafficShapingHandler) trafficShapingHandler, this);
100             timeout = timer.newTimeout(timerTask, checkInterval.get(), TimeUnit.MILLISECONDS);
101         }
102     }
103 
104     /**
105      * Stop the monitoring process.
106      */
107     @Override
108     public synchronized void stop() {
109         if (!monitorActive) {
110             return;
111         }
112         monitorActive = false;
113         resetAccounting(milliSecondFromNano());
114         trafficShapingHandler.doAccounting(this);
115         if (timeout != null) {
116             timeout.cancel();
117         }
118     }
119 
120     @Override
121     public void resetCumulativeTime() {
122         for (PerChannel perChannel :
123             ((GlobalChannelTrafficShapingHandler) trafficShapingHandler).channelQueues.values()) {
124             perChannel.channelTrafficCounter.resetCumulativeTime();
125         }
126         super.resetCumulativeTime();
127     }
128 
129 }