netty5/handler/src/main/java/io/netty/handler/traffic/TrafficCounter.java

622 lines
20 KiB
Java
Raw Normal View History

2012-12-23 20:29:45 +01:00
/*
* 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:
*
* https://www.apache.org/licenses/LICENSE-2.0
2012-12-23 20:29:45 +01:00
*
* 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.
*/
package io.netty.handler.traffic;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
2012-12-23 20:29:45 +01:00
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import static io.netty.util.internal.ObjectUtil.checkNotNullWithIAE;
import static java.util.Objects.requireNonNull;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
2012-12-23 20:29:45 +01:00
/**
* Counts the number of read and written bytes for rate-limiting traffic.
* <p>
* It computes the statistics for both inbound and outbound traffic periodically at the given
* {@code checkInterval}, and calls the {@link AbstractTrafficShapingHandler#doAccounting(TrafficCounter)} method back.
* If the {@code checkInterval} is {@code 0}, no accounting will be done and statistics will only be computed at each
* receive or write operation.
* </p>
2012-12-23 20:29:45 +01:00
*/
public class TrafficCounter {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(TrafficCounter.class);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
/**
* @return the time in ms using nanoTime, so not real EPOCH time but elapsed time in ms.
*/
2014-12-29 07:54:56 +01:00
public static long milliSecondFromNano() {
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
return System.nanoTime() / 1000000;
}
2012-12-23 20:29:45 +01:00
/**
* Current written bytes
*/
private final AtomicLong currentWrittenBytes = new AtomicLong();
/**
* Current read bytes
*/
private final AtomicLong currentReadBytes = new AtomicLong();
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
/**
* Last writing time during current check interval
*/
private long writingTime;
/**
* Last reading delay during current check interval
*/
private long readingTime;
2012-12-23 20:29:45 +01:00
/**
* Long life written bytes
*/
private final AtomicLong cumulativeWrittenBytes = new AtomicLong();
/**
* Long life read bytes
*/
private final AtomicLong cumulativeReadBytes = new AtomicLong();
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Last Time where cumulative bytes where reset to zero: this time is a real EPOC time (informative only)
2012-12-23 20:29:45 +01:00
*/
private long lastCumulativeTime;
/**
* Last writing bandwidth
*/
private long lastWriteThroughput;
/**
* Last reading bandwidth
*/
private long lastReadThroughput;
/**
* Last Time Check taken
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
final AtomicLong lastTime = new AtomicLong();
2012-12-23 20:29:45 +01:00
/**
* Last written bytes number during last check interval
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
private volatile long lastWrittenBytes;
2012-12-23 20:29:45 +01:00
/**
* Last read bytes number during last check interval
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
private volatile long lastReadBytes;
2012-12-23 20:29:45 +01:00
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Last future writing time during last check interval
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
private volatile long lastWritingTime;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Last reading time during last check interval
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
private volatile long lastReadingTime;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Real written bytes
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
private final AtomicLong realWrittenBytes = new AtomicLong();
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Real writing bandwidth
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
private long realWriteThroughput;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
2012-12-23 20:29:45 +01:00
/**
* Delay between two captures
*/
2013-01-10 07:23:58 +01:00
final AtomicLong checkInterval = new AtomicLong(
2012-12-23 20:29:45 +01:00
AbstractTrafficShapingHandler.DEFAULT_CHECK_INTERVAL);
// default 1 s
/**
* Name of this Monitor
*/
final String name;
/**
* The associated TrafficShapingHandler
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
final AbstractTrafficShapingHandler trafficShapingHandler;
2012-12-23 20:29:45 +01:00
/**
* Executor that will run the monitor
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
final ScheduledExecutorService executor;
2012-12-23 20:29:45 +01:00
/**
* Monitor created once in start()
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
Runnable monitor;
2012-12-23 20:29:45 +01:00
/**
* used in stop() to cancel the timer
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
volatile ScheduledFuture<?> scheduledFuture;
2012-12-23 20:29:45 +01:00
/**
* Is Monitor active
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
volatile boolean monitorActive;
2012-12-23 20:29:45 +01:00
/**
* Class to implement monitoring at fix delay
*
*/
private final class TrafficMonitoringTask implements Runnable {
2012-12-23 20:29:45 +01:00
@Override
public void run() {
if (!monitorActive) {
2012-12-23 20:29:45 +01:00
return;
}
resetAccounting(milliSecondFromNano());
if (trafficShapingHandler != null) {
trafficShapingHandler.doAccounting(TrafficCounter.this);
2012-12-23 20:29:45 +01:00
}
}
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Start the monitoring process.
2012-12-23 20:29:45 +01:00
*/
public synchronized void start() {
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (monitorActive) {
return;
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
lastTime.set(milliSecondFromNano());
long localCheckInterval = checkInterval.get();
// if executor is null, it means it is piloted by a GlobalChannelTrafficCounter, so no executor
if (localCheckInterval > 0 && executor != null) {
monitorActive = true;
monitor = new TrafficMonitoringTask();
scheduledFuture =
executor.scheduleAtFixedRate(monitor, 0, localCheckInterval, TimeUnit.MILLISECONDS);
2012-12-23 20:29:45 +01:00
}
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Stop the monitoring process.
2012-12-23 20:29:45 +01:00
*/
public synchronized void stop() {
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (!monitorActive) {
return;
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
monitorActive = false;
resetAccounting(milliSecondFromNano());
if (trafficShapingHandler != null) {
trafficShapingHandler.doAccounting(this);
}
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
2012-12-23 20:29:45 +01:00
}
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Reset the accounting on Read and Write.
2012-12-23 20:29:45 +01:00
*
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @param newLastTime the milliseconds unix timestamp that we should be considered up-to-date for.
2012-12-23 20:29:45 +01:00
*/
synchronized void resetAccounting(long newLastTime) {
long interval = newLastTime - lastTime.getAndSet(newLastTime);
if (interval == 0) {
// nothing to do
return;
2012-12-23 20:29:45 +01:00
}
2014-12-29 07:54:56 +01:00
if (logger.isDebugEnabled() && interval > checkInterval() << 1) {
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
logger.debug("Acct schedule not ok: " + interval + " > 2*" + checkInterval() + " from " + name);
}
lastReadBytes = currentReadBytes.getAndSet(0);
lastWrittenBytes = currentWrittenBytes.getAndSet(0);
lastReadThroughput = lastReadBytes * 1000 / interval;
// nb byte / checkInterval in ms * 1000 (1s)
lastWriteThroughput = lastWrittenBytes * 1000 / interval;
// nb byte / checkInterval in ms * 1000 (1s)
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
realWriteThroughput = realWrittenBytes.getAndSet(0) * 1000 / interval;
lastWritingTime = Math.max(lastWritingTime, writingTime);
lastReadingTime = Math.max(lastReadingTime, readingTime);
2012-12-23 20:29:45 +01:00
}
/**
* Constructor with the {@link AbstractTrafficShapingHandler} that hosts it, the {@link ScheduledExecutorService}
* to use, its name, the checkInterval between two computations in milliseconds.
*
* @param executor
* the underlying executor service for scheduling checks, might be null when used
* from {@link GlobalChannelTrafficCounter}.
* @param name
* the name given to this monitor.
* @param checkInterval
* the checkInterval in millisecond between two computations.
*/
public TrafficCounter(ScheduledExecutorService executor, String name, long checkInterval) {
requireNonNull(name, "name");
trafficShapingHandler = null;
this.executor = executor;
this.name = name;
init(checkInterval);
}
2012-12-23 20:29:45 +01:00
/**
* Constructor with the {@link AbstractTrafficShapingHandler} that hosts it, the Timer to use, its
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* name, the checkInterval between two computations in millisecond.
*
* @param trafficShapingHandler
* the associated AbstractTrafficShapingHandler.
* @param executor
* the underlying executor service for scheduling checks, might be null when used
* from {@link GlobalChannelTrafficCounter}.
* @param name
* the name given to this monitor.
* @param checkInterval
* the checkInterval in millisecond between two computations.
*/
public TrafficCounter(
AbstractTrafficShapingHandler trafficShapingHandler, ScheduledExecutorService executor,
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
String name, long checkInterval) {
this.name = requireNonNull(name, "name");
this.trafficShapingHandler = checkNotNullWithIAE(trafficShapingHandler, "trafficShapingHandler");
2012-12-23 20:29:45 +01:00
this.executor = executor;
init(checkInterval);
}
private void init(long checkInterval) {
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
// absolute time: informative only
2012-12-23 20:29:45 +01:00
lastCumulativeTime = System.currentTimeMillis();
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
writingTime = milliSecondFromNano();
readingTime = writingTime;
lastWritingTime = writingTime;
lastReadingTime = writingTime;
2012-12-23 20:29:45 +01:00
configure(checkInterval);
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Change checkInterval between two computations in millisecond.
2012-12-23 20:29:45 +01:00
*
2017-04-19 22:37:03 +02:00
* @param newCheckInterval The new check interval (in milliseconds)
2012-12-23 20:29:45 +01:00
*/
2017-04-19 22:37:03 +02:00
public void configure(long newCheckInterval) {
long newInterval = newCheckInterval / 10 * 10;
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (checkInterval.getAndSet(newInterval) != newInterval) {
2012-12-23 20:29:45 +01:00
if (newInterval <= 0) {
stop();
// No more active monitoring
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
lastTime.set(milliSecondFromNano());
2012-12-23 20:29:45 +01:00
} else {
// Restart
stop();
2012-12-23 20:29:45 +01:00
start();
}
}
}
/**
* Computes counters for Read.
*
* @param recv
* the size in bytes to read
*/
void bytesRecvFlowControl(long recv) {
currentReadBytes.addAndGet(recv);
cumulativeReadBytes.addAndGet(recv);
}
/**
* Computes counters for Write.
*
* @param write
* the size in bytes to write
*/
void bytesWriteFlowControl(long write) {
currentWrittenBytes.addAndGet(write);
cumulativeWrittenBytes.addAndGet(write);
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* Computes counters for Real Write.
2012-12-23 20:29:45 +01:00
*
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @param write
* the size in bytes to write
*/
void bytesRealWriteFlowControl(long write) {
realWrittenBytes.addAndGet(write);
}
/**
2012-12-23 20:29:45 +01:00
* @return the current checkInterval between two computations of traffic counter
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* in millisecond.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long checkInterval() {
2012-12-23 20:29:45 +01:00
return checkInterval.get();
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the Read Throughput in bytes/s computes in the last check interval.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long lastReadThroughput() {
2012-12-23 20:29:45 +01:00
return lastReadThroughput;
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the Write Throughput in bytes/s computes in the last check interval.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long lastWriteThroughput() {
2012-12-23 20:29:45 +01:00
return lastWriteThroughput;
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the number of bytes read during the last check Interval.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long lastReadBytes() {
2012-12-23 20:29:45 +01:00
return lastReadBytes;
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the number of bytes written during the last check Interval.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long lastWrittenBytes() {
2012-12-23 20:29:45 +01:00
return lastWrittenBytes;
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the current number of bytes read since the last checkInterval.
*/
2013-01-17 07:06:46 +01:00
public long currentReadBytes() {
2012-12-23 20:29:45 +01:00
return currentReadBytes.get();
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the current number of bytes written since the last check Interval.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long currentWrittenBytes() {
2012-12-23 20:29:45 +01:00
return currentWrittenBytes.get();
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the Time in millisecond of the last check as of System.currentTimeMillis().
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public long lastTime() {
2012-12-23 20:29:45 +01:00
return lastTime.get();
}
/**
* @return the cumulativeWrittenBytes
*/
2013-01-17 07:06:46 +01:00
public long cumulativeWrittenBytes() {
2012-12-23 20:29:45 +01:00
return cumulativeWrittenBytes.get();
}
/**
* @return the cumulativeReadBytes
*/
2013-01-17 07:06:46 +01:00
public long cumulativeReadBytes() {
2012-12-23 20:29:45 +01:00
return cumulativeReadBytes.get();
}
/**
* @return the lastCumulativeTime in millisecond as of System.currentTimeMillis()
* when the cumulative counters were reset to 0.
*/
2013-01-17 07:06:46 +01:00
public long lastCumulativeTime() {
2012-12-23 20:29:45 +01:00
return lastCumulativeTime;
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the realWrittenBytes
*/
public AtomicLong getRealWrittenBytes() {
return realWrittenBytes;
}
/**
* @return the realWriteThroughput
*/
public long getRealWriteThroughput() {
return realWriteThroughput;
}
/**
* Reset both read and written cumulative bytes counters and the associated absolute time
* from System.currentTimeMillis().
2012-12-23 20:29:45 +01:00
*/
public void resetCumulativeTime() {
lastCumulativeTime = System.currentTimeMillis();
cumulativeReadBytes.set(0);
cumulativeWrittenBytes.set(0);
}
/**
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* @return the name of this TrafficCounter.
2012-12-23 20:29:45 +01:00
*/
2013-01-17 07:06:46 +01:00
public String name() {
2012-12-23 20:29:45 +01:00
return name;
}
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
/**
* Returns the time to wait (if any) for the given length message, using the given limitTraffic and the max wait
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* time.
*
* @param size
* the recv size
* @param limitTraffic
* the traffic limit in bytes per second.
* @param maxTime
* the max time in ms to wait in case of excess of traffic.
* @return the current time to wait (in ms) if needed for Read operation.
*/
@Deprecated
public long readTimeToWait(final long size, final long limitTraffic, final long maxTime) {
return readTimeToWait(size, limitTraffic, maxTime, milliSecondFromNano());
}
/**
* Returns the time to wait (if any) for the given length message, using the given limitTraffic and the max wait
* time.
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*
* @param size
* the recv size
* @param limitTraffic
* the traffic limit in bytes per second
* @param maxTime
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* the max time in ms to wait in case of excess of traffic.
* @param now the current time
* @return the current time to wait (in ms) if needed for Read operation.
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
public long readTimeToWait(final long size, final long limitTraffic, final long maxTime, final long now) {
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
bytesRecvFlowControl(size);
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (size == 0 || limitTraffic == 0) {
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
return 0;
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
final long lastTimeCheck = lastTime.get();
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
long sum = currentReadBytes.get();
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
long localReadingTime = readingTime;
long lastRB = lastReadBytes;
final long interval = now - lastTimeCheck;
long pastDelay = Math.max(lastReadingTime - lastTimeCheck, 0);
if (interval > AbstractTrafficShapingHandler.MINIMAL_WAIT) {
// Enough interval time to compute shaping
long time = sum * 1000 / limitTraffic - interval + pastDelay;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
if (time > AbstractTrafficShapingHandler.MINIMAL_WAIT) {
if (logger.isDebugEnabled()) {
2014-12-29 07:54:56 +01:00
logger.debug("Time: " + time + ':' + sum + ':' + interval + ':' + pastDelay);
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
}
if (time > maxTime && now + time - localReadingTime > maxTime) {
time = maxTime;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
readingTime = Math.max(localReadingTime, now + time);
return time;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
readingTime = Math.max(localReadingTime, now);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
return 0;
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
// take the last read interval check to get enough interval time
long lastsum = sum + lastRB;
long lastinterval = interval + checkInterval.get();
long time = lastsum * 1000 / limitTraffic - lastinterval + pastDelay;
if (time > AbstractTrafficShapingHandler.MINIMAL_WAIT) {
if (logger.isDebugEnabled()) {
2014-12-29 07:54:56 +01:00
logger.debug("Time: " + time + ':' + lastsum + ':' + lastinterval + ':' + pastDelay);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (time > maxTime && now + time - localReadingTime > maxTime) {
time = maxTime;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
readingTime = Math.max(localReadingTime, now + time);
return time;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
readingTime = Math.max(localReadingTime, now);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
return 0;
}
/**
* Returns the time to wait (if any) for the given length message, using the given limitTraffic and
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* the max wait time.
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*
* @param size
* the write size
* @param limitTraffic
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* the traffic limit in bytes per second.
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
* @param maxTime
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
* the max time in ms to wait in case of excess of traffic.
* @return the current time to wait (in ms) if needed for Write operation.
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
*/
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
@Deprecated
public long writeTimeToWait(final long size, final long limitTraffic, final long maxTime) {
return writeTimeToWait(size, limitTraffic, maxTime, milliSecondFromNano());
}
/**
* Returns the time to wait (if any) for the given length message, using the given limitTraffic and
* the max wait time.
*
* @param size
* the write size
* @param limitTraffic
* the traffic limit in bytes per second.
* @param maxTime
* the max time in ms to wait in case of excess of traffic.
* @param now the current time
* @return the current time to wait (in ms) if needed for Write operation.
*/
public long writeTimeToWait(final long size, final long limitTraffic, final long maxTime, final long now) {
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
bytesWriteFlowControl(size);
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (size == 0 || limitTraffic == 0) {
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
return 0;
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
final long lastTimeCheck = lastTime.get();
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
long sum = currentWrittenBytes.get();
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
long lastWB = lastWrittenBytes;
long localWritingTime = writingTime;
long pastDelay = Math.max(lastWritingTime - lastTimeCheck, 0);
final long interval = now - lastTimeCheck;
if (interval > AbstractTrafficShapingHandler.MINIMAL_WAIT) {
// Enough interval time to compute shaping
long time = sum * 1000 / limitTraffic - interval + pastDelay;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
if (time > AbstractTrafficShapingHandler.MINIMAL_WAIT) {
if (logger.isDebugEnabled()) {
2014-12-29 07:54:56 +01:00
logger.debug("Time: " + time + ':' + sum + ':' + interval + ':' + pastDelay);
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
}
if (time > maxTime && now + time - localWritingTime > maxTime) {
time = maxTime;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
writingTime = Math.max(localWritingTime, now + time);
return time;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
writingTime = Math.max(localWritingTime, now);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
return 0;
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
// take the last write interval check to get enough interval time
long lastsum = sum + lastWB;
long lastinterval = interval + checkInterval.get();
long time = lastsum * 1000 / limitTraffic - lastinterval + pastDelay;
if (time > AbstractTrafficShapingHandler.MINIMAL_WAIT) {
if (logger.isDebugEnabled()) {
2014-12-29 07:54:56 +01:00
logger.debug("Time: " + time + ':' + lastsum + ':' + lastinterval + ':' + pastDelay);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
if (time > maxTime && now + time - localWritingTime > maxTime) {
time = maxTime;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
writingTime = Math.max(localWritingTime, now + time);
return time;
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
}
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
writingTime = Math.max(localWritingTime, now);
[#2721] Improve Traffic Shaping handler Motivation: Currently Traffic Shaping is using 1 timer only and could lead to "partial" wrong bandwidth computation when "short" time occurs between adding used bytes and when the TrafficCounter updates itself and finally when the traffic is computed. Indeed, the TrafficCounter is updated every x delay and it is at the same time saved into "lastXxxxBytes" and set to 0. Therefore, when one request the counter, it first updates the TrafficCounter with the added used bytes. If this value is set just before the TrafficCounter is updated, then the bandwidth computation will use the TrafficCounter with a "0" value (this value being reset once the delay occurs). Therefore, the traffic shaping computation is wrong in rare cases. Secondly the traffic shapping should avoid if possible the "Timeout" effect by not stopping reading or writing more than a maxTime, this maxTime being less than the TimeOut limit. Thirdly the traffic shapping in read had an issue since the readOp was not set but should, turning in no read blocking from socket point of view. Modifications: The TrafficCounter has 2 new methods that compute the time to wait according to read or write) using in priority the currentXxxxBytes (as before), but could used (if current is at 0) the lastXxxxxBytes, and therefore having more chance to take into account the real traffic. Moreover the Handler could change the default "max time to wait", which is by default set to half of "standard" Time Out (30s:2 = 15s). Finally we add the setAutoRead(boolean) accordingly to the situation, as proposed in #2696 (this pull request is in error for unknown reason). Result: The Traffic Shaping is better take into account (no 0 value when it shouldn't) and it tries to not block traffic more than Time Out event. Moreover the read is really stopped from socket point of view. This version is similar to #2388 and #2450. This version is for V4.1, and includes the #2696 pull request to ease the merge process. It is compatible with master too. Including also #2748 The test minimizes time check by reducing to 66ms steps (55s).
2014-08-01 10:13:00 +02:00
return 0;
}
2012-12-23 20:29:45 +01:00
@Override
public String toString() {
Fix big transfer and Write traffic shaping issues Motivation: Several issues were shown by various ticket (#2900 #2956). Also use the improvement on writability user management from #3036. And finally add a mixte handler, both for Global and Channels, with the advantages of being uniquely created and using less memory and less shaping. Issue #2900 When a huge amount of data are written, the current behavior of the TrafficShaping handler is to limit the delay to 15s, whatever the delay the previous write has. This is wrong, and when a huge amount of writes are done in a short time, the traffic is not correctly shapened. Moreover, there is a high risk of OOM if one is not using in his/her own handler for instance ChannelFuture.addListener() to handle the write bufferisation in the TrafficShapingHandler. This fix use the "user-defined writability flags" from #3036 to allow the TrafficShapingHandlers to "user-defined" managed writability directly, as for reading, thus using the default isWritable() and channelWritabilityChanged(). This allows for instance HttpChunkedInput to be fully compatible. The "bandwidth" compute on write is only on "acquired" write orders, not on "real" write orders, which is wrong from statistic point of view. Issue #2956 When using GlobalTrafficShaping, every write (and read) are synchronized, thus leading to a drop of performance. ChannelTrafficShaping is not touched by this issue since synchronized is then correct (handler is per channel, so the synchronized). Modifications: The current write delay computation takes into account the previous write delay and time to check is the 15s delay (maxTime) is really exceeded or not (using last scheduled write time). The algorithm is simplified and in the same time more accurate. This proposal uses the #3036 improvement on user-defined writability flags. When the real write occurs, the statistics are update accordingly on a new attribute (getRealWriteThroughput()). To limit the synchronisations, all synchronized on GlobalTrafficShapingHandler on submitWrite were removed. They are replaced with a lock per channel (since synchronization is still needed to prevent unordered write per channel), as in the sendAllValid method for the very same reason. Also all synchronized on TrafficCounter on read/writeTimeToWait() are removed as they are unnecessary since already locked before by the caller. Still the creation and remove operations on lock per channel (PerChannel object) are synchronized to prevent concurrency issue on this critical part, but then limited. Additionnal changes: 1) Use System.nanoTime() instead of System.currentTimeMillis() and minimize calls 2) Remove / 10 ° 10 since no more sleep usage 3) Use nanoTime instead of currentTime such that time spend is computed, not real time clock. Therefore the "now" relative time (nanoTime based) is passed on all sub methods. 4) Take care of removal of the handler to force write all pending writes and release read too 8) Review Javadoc to explicit: - recommandations to take into account isWritable - recommandations to provide reasonable message size according to traffic shaping limit - explicit "best effort" traffic shaping behavior when changing configuration dynamically Add a MixteGlobalChannelTrafficShapingHandler which allows to use only one handler for mixing Global and Channel TSH. I enables to save more memory and tries to optimize the traffic among various channels. Result: The traffic shaping is more stable, even with a huge number of writes in short time by taking into consideration last scheduled write time. The current implementation of TrafficShapingHandler using user-defined writability flags and default isWritable() and fireChannelWritabilityChanged works as expected. The statistics are more valuable (asked write vs real write). The Global TrafficShapingHandler should now have less "global" synchronization, hoping to the minimum, but still per Channel as needed. The GlobalChannel TrafficShapingHandler allows to have only one handler for all channels while still offering per channel in addition to global traffic shaping. And finally maintain backward compatibility.
2014-10-25 13:16:56 +02:00
return new StringBuilder(165).append("Monitor ").append(name)
.append(" Current Speed Read: ").append(lastReadThroughput >> 10).append(" KB/s, ")
.append("Asked Write: ").append(lastWriteThroughput >> 10).append(" KB/s, ")
.append("Real Write: ").append(realWriteThroughput >> 10).append(" KB/s, ")
.append("Current Read: ").append(currentReadBytes.get() >> 10).append(" KB, ")
.append("Current asked Write: ").append(currentWrittenBytes.get() >> 10).append(" KB, ")
.append("Current real Write: ").append(realWrittenBytes.get() >> 10).append(" KB").toString();
2012-12-23 20:29:45 +01:00
}
}