| OLD | NEW | 
|---|
| 1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 library microlytics.channels; | 5 library microlytics.channels; | 
| 6 | 6 | 
| 7 import 'dart:async'; | 7 import 'dart:async'; | 
| 8 | 8 | 
| 9 const String ANALYTICS_URL = "https://ssl.google-analytics.com/collect"; | 9 const String ANALYTICS_URL = "https://ssl.google-analytics.com/collect"; | 
| 10 | 10 | 
| 11 abstract class Channel { | 11 abstract class Channel { | 
| 12   void sendData(String data); | 12   void sendData(String data); | 
| 13   void shutdown() {} | 13   void shutdown() {} | 
| 14 } | 14 } | 
| 15 | 15 | 
| 16 /// [Channel] that implements a leaky bucket | 16 /// [Channel] that implements a leaky bucket | 
| 17 /// algorithm to provide rate limiting. | 17 /// algorithm to provide rate limiting. | 
| 18 /// See [http://en.wikipedia.org/wiki/Leaky_bucket]. | 18 /// See [http://en.wikipedia.org/wiki/Leaky_bucket]. | 
| 19 class RateLimitingBufferedChannel extends Channel { | 19 class RateLimitingBufferedChannel extends Channel { | 
| 20   final List<String> _buffer = <String>[]; | 20   final List<String> _buffer = <String>[]; | 
| 21   final Channel _innerChannel; | 21   final Channel _innerChannel; | 
| 22   final int _bufferSizeLimit; | 22   final int _bufferSizeLimit; | 
| 23   Timer _timer; | 23   Timer _timer; | 
| 24 | 24 | 
| 25   RateLimitingBufferedChannel( | 25   RateLimitingBufferedChannel(this._innerChannel, | 
| 26       this._innerChannel, | 26       {int bufferSizeLimit: 10, double packetsPerSecond: 1.0}) | 
| 27       {int bufferSizeLimit: 10, |  | 
| 28         double packetsPerSecond: 1.0}) |  | 
| 29       : this._bufferSizeLimit = bufferSizeLimit { | 27       : this._bufferSizeLimit = bufferSizeLimit { | 
| 30     if (!(packetsPerSecond > 0)) { | 28     if (!(packetsPerSecond > 0)) { | 
| 31       throw new ArgumentError("packetsPerSecond must be larger than zero."); | 29       throw new ArgumentError("packetsPerSecond must be larger than zero."); | 
| 32     } | 30     } | 
| 33 | 31 | 
| 34     int transmitDelay = (1000 / packetsPerSecond).floor(); | 32     int transmitDelay = (1000 / packetsPerSecond).floor(); | 
| 35     _timer = new Timer.periodic( | 33     _timer = new Timer.periodic( | 
| 36         new Duration(milliseconds: transmitDelay), _onTimerTick); | 34         new Duration(milliseconds: transmitDelay), _onTimerTick); | 
| 37   } | 35   } | 
| 38 | 36 | 
| 39   void _onTimerTick(_) { | 37   void _onTimerTick(_) { | 
| 40     if (_buffer.length > 0) { | 38     if (_buffer.length > 0) { | 
| 41       String item = _buffer.removeLast(); | 39       String item = _buffer.removeLast(); | 
| 42       _innerChannel.sendData(item); | 40       _innerChannel.sendData(item); | 
| 43     } | 41     } | 
| 44   } | 42   } | 
| 45 | 43 | 
| 46   void sendData(String data) { | 44   void sendData(String data) { | 
| 47     if (_buffer.length >= _bufferSizeLimit) return; | 45     if (_buffer.length >= _bufferSizeLimit) return; | 
| 48     _buffer.add(data); | 46     _buffer.add(data); | 
| 49   } | 47   } | 
| 50 | 48 | 
| 51   void shutdown() { | 49   void shutdown() { | 
| 52     _timer.cancel(); | 50     _timer.cancel(); | 
| 53     _innerChannel.shutdown(); | 51     _innerChannel.shutdown(); | 
| 54   } | 52   } | 
| 55 } | 53 } | 
| OLD | NEW | 
|---|