/// <summary> /// Limits the bandwith used by the subsequent stages in the aspnetcore pipeline. /// </summary> /// <param name="getMaxBytesPerSecond"> /// A delegate to retrieve the maximum number of bytes per second to be transferred. /// Allows you to supply different values at runtime. Use 0 or a negative number to specify infinite bandwidth. /// </param> /// <returns>A middleware delegate.</returns> /// <exception cref="System.ArgumentNullException">getMaxBytesPerSecond</exception> public static MidFunc MaxBandwidthPerRequest(Func <RequestContext, int> getMaxBytesPerSecond) { if (getMaxBytesPerSecond == null) { throw new ArgumentNullException(nameof(getMaxBytesPerSecond)); } return (next => async context => { var requestBodyStream = context.Request.Body ?? Stream.Null; var responseBodyStream = context.Response.Body; var limitsRequestContext = new RequestContext(context.Request); var requestTokenBucket = new FixedTokenBucket( () => getMaxBytesPerSecond(limitsRequestContext)); var responseTokenBucket = new FixedTokenBucket( () => getMaxBytesPerSecond(limitsRequestContext)); // ReSharper disable once ArrangeBraces_using using (requestTokenBucket.RegisterRequest()) using (responseTokenBucket.RegisterRequest()) { context.Request.Body = new ThrottledStream(requestBodyStream, requestTokenBucket); context.Response.Body = new ThrottledStream(responseBodyStream, responseTokenBucket); //TODO consider SendFile interception await next(context).ConfigureAwait(false); } }); }
/// <summary> /// Limits the bandwith used by the subsequent stages in the owin pipeline. /// </summary> /// <param name="getBytesPerSecond">A delegate to retrieve the maximum number of bytes per second to be transferred. /// Allows you to supply different values at runtime. Use 0 or a negative number to specify infinite bandwidth.</param> /// <returns>An OWIN middleware delegate.</returns> /// <exception cref="System.ArgumentNullException">getMaxBytesToWrite</exception> public static MidFunc MaxBandwidthGlobal(Func <int> getBytesPerSecond) { getBytesPerSecond.MustNotNull("getMaxBytesToWrite"); var logger = LogProvider.GetLogger("LimitsMiddleware.MaxBandwidthGlobal"); var requestTokenBucket = new FixedTokenBucket(getBytesPerSecond); var responseTokenBucket = new FixedTokenBucket(getBytesPerSecond); logger.Debug("Configure streams to be globally limited."); return (next => async env => { using (requestTokenBucket.RegisterRequest()) using (responseTokenBucket.RegisterRequest()) { var context = new OwinContext(env); Stream requestBodyStream = context.Request.Body ?? Stream.Null; Stream responseBodyStream = context.Response.Body; context.Request.Body = new ThrottledStream(requestBodyStream, requestTokenBucket); context.Response.Body = new ThrottledStream(responseBodyStream, responseTokenBucket); //TODO consider SendFile interception await next(env).ConfigureAwait(false); } }); }
/// <summary> /// Limits the bandwith used by the subsequent stages in the owin pipeline. /// </summary> /// <param name="getMaxBytesPerSecond"> /// A delegate to retrieve the maximum number of bytes per second to be transferred. /// Allows you to supply different values at runtime. Use 0 or a negative number to specify infinite bandwidth. /// </param> /// <returns>An OWIN middleware delegate.</returns> /// <exception cref="System.ArgumentNullException">getMaxBytesPerSecond</exception> public static MidFunc MaxBandwidthPerRequest(Func <RequestContext, int> getMaxBytesPerSecond) { getMaxBytesPerSecond.MustNotNull("getMaxBytesPerSecond"); return (next => async env => { var context = new OwinContext(env); Stream requestBodyStream = context.Request.Body ?? Stream.Null; Stream responseBodyStream = context.Response.Body; var limitsRequestContext = new RequestContext(context.Request); var requestTokenBucket = new FixedTokenBucket( () => getMaxBytesPerSecond(limitsRequestContext)); var responseTokenBucket = new FixedTokenBucket( () => getMaxBytesPerSecond(limitsRequestContext)); using (requestTokenBucket.RegisterRequest()) using (responseTokenBucket.RegisterRequest()) { context.Request.Body = new ThrottledStream(requestBodyStream, requestTokenBucket); context.Response.Body = new ThrottledStream(responseBodyStream, responseTokenBucket); //TODO consider SendFile interception await next(env).ConfigureAwait(false); } }); }
public ThrottledStream( Stream innerStream, FixedTokenBucket fixedTokenBucket) { innerStream.MustNotNull("innerStream"); _innerStream = innerStream; _tokenBucket = fixedTokenBucket; }
public ThrottledStream(Stream innerStream, FixedTokenBucket fixedTokenBucket) { if (innerStream == null) { throw new ArgumentNullException(nameof(innerStream)); } _innerStream = innerStream; _tokenBucket = fixedTokenBucket; }
static void Main(string[] args) { // int x =10; IThrottleStrategy strategy = new FixedTokenBucket(100, 10, 1000); Throttler throttle = new Throttler(strategy); if (!throttle.CanConsume()) { Console.WriteLine("CanConsume"); } // 策略模式 Context context = new Context(new ConcreateStrategyA()); context.ContextInterfact(); // 备忘录模式 Originator originator = new Originator(); originator.State = "on"; originator.Show(); Caretaker caretaker = new Caretaker(); caretaker.Memento = originator.CreateMemento(); originator.State = "off"; originator.Show(); originator.SetMemento(caretaker.Memento); originator.Show(); // 命令模式 Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoke invoke = new Invoke(command); invoke.Execute(); Console.WriteLine("Hello World!"); }
private static async Task Test() { var Speed = 200; FixedTokenBucket limiter; /* * 250: 1, 1, 4 * 10: 1,1, 100 * 0.2: 1 秒中 0.2 个,则 5 秒 1个 */ if (Speed >= 1) { var defaultTimeUnit = (int)(1000 / Speed); limiter = new FixedTokenBucket(1, 1, defaultTimeUnit); } else { var defaultTimeUnit = (int)((1 / Speed) * 1000); limiter = new FixedTokenBucket(1, 1, defaultTimeUnit); } var now = DateTime.Now; for (var i = 1; i < 100000000; ++i) { while (limiter.ShouldThrottle(1, out var waitTimeMillis)) { await Task.Delay(waitTimeMillis); } if (i > 15 && (i % 10) == 0) { var seconds = (DateTime.Now - now).TotalSeconds; var speed = i / seconds; Console.WriteLine($"Speed: {speed}"); } } }
/// <summary> /// Limits the bandwith used by the subsequent stages in the aspnetcore pipeline. /// </summary> /// <param name="getBytesPerSecond"> /// A delegate to retrieve the maximum number of bytes per second to be transferred. /// Allows you to supply different values at runtime. Use 0 or a negative number to specify infinite bandwidth. /// </param> /// <param name="loggerName">(Optional) The name of the logger log messages are written to.</param> /// <returns>A middleware delegate.</returns> /// <exception cref="System.ArgumentNullException">getMaxBytesToWrite</exception> public static MidFunc MaxBandwidthGlobal(Func <int> getBytesPerSecond, string loggerName = null) { if (getBytesPerSecond == null) { throw new ArgumentNullException(nameof(getBytesPerSecond)); } loggerName = string.IsNullOrWhiteSpace(loggerName) ? $"{nameof(LimitsMiddleware)}.{nameof(MaxBandwidthGlobal)}" : loggerName; var logger = LogProvider.GetLogger(loggerName); var requestTokenBucket = new FixedTokenBucket(getBytesPerSecond); var responseTokenBucket = new FixedTokenBucket(getBytesPerSecond); logger.Debug("Configure streams to be globally limited to."); return (next => async context => { // ReSharper disable once ArrangeBraces_using using (requestTokenBucket.RegisterRequest()) using (responseTokenBucket.RegisterRequest()) { var requestBodyStream = context.Request.Body ?? Stream.Null; var responseBodyStream = context.Response.Body; context.Request.Body = new ThrottledStream(requestBodyStream, requestTokenBucket); context.Response.Body = new ThrottledStream(responseBodyStream, responseTokenBucket); //TODO consider SendFile interception await next(context).ConfigureAwait(false); } }); }
public void SetUp() { bucket = new FixedTokenBucket(MAX_TOKENS, REFILL_INTERVAL, 1000); }
public PerSecondRateLimiter(int requestsPerSecond) { bucket = new FixedTokenBucket(1, 1, 1000 / requestsPerSecond); }
public void SetUp() { bucket = new FixedTokenBucket(MAX_TOKENS, REFILL_INTERVAL, 1000); }
public FixedTokenBucketTests() { _bucket = new FixedTokenBucket(() => MAX_TOKENS, () => _getUtcNow()); }