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.netty.handler.traffic;
17
18 import static io.netty.util.internal.ObjectUtil.checkNotNullWithIAE;
19
20 import io.netty.handler.traffic.GlobalChannelTrafficShapingHandler.PerChannel;
21
22 import java.util.concurrent.ScheduledExecutorService;
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 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 ScheduledExecutorService 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(true);
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 }