예제 #1
0
        /// <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);
                    }
            });
        }
예제 #2
0
        /// <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);
                    }
            });
        }
예제 #4
0
        public ThrottledStream(
            Stream innerStream,
            FixedTokenBucket fixedTokenBucket)
        {
            innerStream.MustNotNull("innerStream");

            _innerStream = innerStream;
            _tokenBucket = fixedTokenBucket;
        }
예제 #5
0
        public ThrottledStream(Stream innerStream, FixedTokenBucket fixedTokenBucket)
        {
            if (innerStream == null)
            {
                throw new ArgumentNullException(nameof(innerStream));
            }

            _innerStream = innerStream;
            _tokenBucket = fixedTokenBucket;
        }
예제 #6
0
        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!");
        }
예제 #7
0
        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}");
                }
            }
        }
예제 #8
0
        /// <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);
 }
예제 #10
0
 public PerSecondRateLimiter(int requestsPerSecond)
 {
     bucket = new FixedTokenBucket(1, 1, 1000 / requestsPerSecond);
 }
예제 #11
0
 public void SetUp()
 {
     bucket = new FixedTokenBucket(MAX_TOKENS, REFILL_INTERVAL, 1000);
 }
 public FixedTokenBucketTests()
 {
     _bucket = new FixedTokenBucket(() => MAX_TOKENS, () => _getUtcNow());
 }