/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

/**
 * Implementation of a Traffic Shaping Handler and Dynamic Statistics.<br>
 * <br><br>
 *
 *
 * <P>The main goal of this package is to allow to shape the traffic (bandwidth limitation),
 * but also to get statistics on how many bytes are read or written. Both functions can
 * be active or inactive (traffic or statistics).</P>
 *
 * <P>Two classes implement this behavior:<br>
 * <ul>
 * <li>{@link org.jboss.netty.handler.traffic.TrafficCounter}: this class implements the counters
 *     needed by the handlers. It can be accessed to get some extra information like the read or
 *     write bytes since last check, the read and write bandwidth from last check...</li><br><br>
 *
 * <li>{@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}: this abstract class
 *     implements the kernel of the traffic shaping. It could be extended to fit your needs. Two
 *     classes are proposed as default implementations: see
 *     {@link org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler} and
 *     {@link org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler} respectively for
 *     Channel traffic shaping and Global traffic shaping.</li><br><br>
 *
 * The insertion in the pipeline of one of those handlers can be wherever you want, but
 * <b>it must be placed before any <tt>{@link org.jboss.netty.handler.execution.MemoryAwareThreadPoolExecutor}</tt>
 * in your pipeline</b>.<br>
 * <b><i>It is really recommended to have such a</i>
 * <tt>{@link org.jboss.netty.handler.execution.MemoryAwareThreadPoolExecutor}</tt>
 * <i>(either non ordered or </i>
 * <tt>{@link org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor}</tt>
 * <i>) in your pipeline</i></b>
 * when you want to use this feature with some real traffic shaping, since it will allow to relax the constraint on
 * NioWorker to do other jobs if necessary.<br>
 * Instead, if you don't, you can have the following situation: if there are more clients
 * connected and doing data transfer (either in read or write) than NioWorker, your global performance can be under
 * your specifications or even sometimes it will block for a while which can turn to "timeout" operations.
 * For instance, let says that you've got 2 NioWorkers, and 10 clients wants to send data to your server.
 * If you set a bandwidth limitation of 100KB/s for each channel (client), you could have a final limitation of about
 * 60KB/s for each channel since NioWorkers are stopping by this handler.<br>
 * When it is used as a read traffic shaper, the handler will set the channel as not readable, so as to relax the
 * NioWorkers.<br><br>
 * An {@link org.jboss.netty.util.ObjectSizeEstimator} can be passed at construction to specify what
 * is the size of the object to be read or write accordingly to the type of
 * object. If not specified, it will used the {@link org.jboss.netty.util.DefaultObjectSizeEstimator}
 * implementation.<br><br>
 * </ul></P>
 *
 * <P>Standard use could be as follow:</P>
 *
 * <P><ul>
 * <li>To activate or deactivate the traffic shaping, change the value corresponding to your desire as
 * [Global or per Channel] [Write or Read] Limitation in byte/s.</li><br>
 * A value of <tt>0</tt>
 * stands for no limitation, so the traffic shaping is deactivate (on what you specified).<br>
 * You can either change those values with the method <tt>configure</tt> in
 * {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}.<br>
 * <br>
 *
 * <li>To activate or deactivate the statistics, you can adjust the delay to a low (suggested not less than 200ms
 * for efficiency reasons) or a high value (let say 24H in millisecond is huge enough to not get the problem)
 * or even using <tt>0</tt> which means no computation will be done.</li><br>
 * If you want to do anything with this statistics, just override the <tt>doAccounting</tt> method.<br>
 * This interval can be changed either from the method <tt>configure</tt> in
 * {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}
 * or directly using the method <tt>configure</tt> of {@link org.jboss.netty.handler.traffic.TrafficCounter}.<br><br>
 *
 * </ul></P><br><br>
 *
 * <P>So in your application you will create your own TrafficShapingHandler and set the values to fit your needs.</P>
 * <tt>XXXXXTrafficShapingHandler myHandler = new XXXXXTrafficShapingHandler(timer);</tt><br><br>
 * timer could be created using <tt>HashedWheelTimer</tt> and XXXXX could be either
 * Global or Channel<br>
 * <tt>pipeline.addLast("XXXXX_TRAFFIC_SHAPING", myHandler);</tt><br>
 * <tt>...</tt><br>
 * <tt>pipeline.addLast("MemoryExecutor",new ExecutionHandler(memoryAwareThreadPoolExecutor));</tt><br><br>
 * <P>Note that a new {@link org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler} must be
 * created for each new channel, but only one {@link org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler}
 * must be created for all channels.</P>
 *
 * <P>Note also that you can create different GlobalTrafficShapingHandler if you want to separate classes of
 * channels (for instance either from business point of view or from bind address point of view).</P>
 *
 * @apiviz.exclude ^java\.lang\.
 */
package org.jboss.netty.handler.traffic;

