Beispiel #1
0
 public override void Dispose()
 {
     latchSubscription?.Dispose();
     stream?.Unsubscribe();
     latchSubscription = null;
     stream            = null;
     base.Dispose();
 }
Beispiel #2
0
        public RollingCommandMaxConcurrencyStreamTest(ITestOutputHelper output)
            : base()
        {
            this.output = output;

            RollingCommandMaxConcurrencyStream.Reset();
            HystrixCommandStartStream.Reset();
        }
        public void TestConcurrencyStreamProperlyFiltersOutSemaphoreRejections()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-H");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(GetSubscriber(output, latch));

            // 10 commands executed concurrently on different caller threads should saturate semaphore
            // once these are in-flight, execute 10 more concurrently on new caller threads.
            // since these are semaphore-rejected, the max concurrency should be 10
            List <Command> saturators = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                saturators.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 400, ExecutionIsolationStrategy.SEMAPHORE));
            }

            List <Command> rejected = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                rejected.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 100, ExecutionIsolationStrategy.SEMAPHORE));
            }

            // List<long> startTimes = new List<long>();
            foreach (Command saturatingCmd in saturators)
            {
                Task t = new Task(
                    () =>
                {
                    saturatingCmd.Observe();
                }, CancellationToken.None,
                    TaskCreationOptions.LongRunning);
                t.Start();
            }

            Time.Wait(30);

            foreach (Command rejectedCmd in rejected)
            {
                Task t = new Task(
                    () =>
                {
                    rejectedCmd.Observe();
                }, CancellationToken.None,
                    TaskCreationOptions.LongRunning);
                t.Start();
            }

            Assert.True(latch.Wait(10000));
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(10, stream.LatestRollingMax);
        }
        public void TestEmptyStreamProducesZeros()
        {
            IHystrixCommandKey key   = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-A");
            CountdownEvent     latch = new CountdownEvent(1);
            var observer             = new LatchedObserver(output, latch);

            stream            = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            latchSubscription = stream.Observe().Subscribe(observer);
            Assert.True(Time.WaitUntil(() => observer.StreamRunning, 500), "Stream failed to start");

            Assert.True(WaitForLatchedObserverToUpdate(observer, 1, 500, output), "Latch took to long to update");

            Assert.Equal(0, stream.LatestRollingMax);
        }
 public static void ShutdownThreads()
 {
     CumulativeCommandEventCounterStream.Reset();
     CumulativeThreadPoolEventCounterStream.Reset();
     RollingCommandEventCounterStream.Reset();
     RollingThreadPoolEventCounterStream.Reset();
     RollingCollapserEventCounterStream.Reset();
     RollingCollapserEventCounterStream.Reset();
     HealthCountsStream.Reset();
     RollingCollapserBatchSizeDistributionStream.Reset();
     RollingCommandLatencyDistributionStream.Reset();
     RollingCommandUserLatencyDistributionStream.Reset();
     RollingCommandMaxConcurrencyStream.Reset();
     RollingThreadPoolMaxConcurrencyStream.Reset();
 }
        HystrixCommandMetrics(IHystrixCommandKey key, IHystrixCommandGroupKey commandGroup, IHystrixThreadPoolKey threadPoolKey, IHystrixCommandOptions properties, HystrixEventNotifier eventNotifier) : base(null)
        {
            this.key           = key;
            this.group         = commandGroup;
            this.threadPoolKey = threadPoolKey;
            this.properties    = properties;

            healthCountsStream = HealthCountsStream.GetInstance(key, properties);
            rollingCommandEventCounterStream    = RollingCommandEventCounterStream.GetInstance(key, properties);
            cumulativeCommandEventCounterStream = CumulativeCommandEventCounterStream.GetInstance(key, properties);

            rollingCommandLatencyDistributionStream     = RollingCommandLatencyDistributionStream.GetInstance(key, properties);
            rollingCommandUserLatencyDistributionStream = RollingCommandUserLatencyDistributionStream.GetInstance(key, properties);
            rollingCommandMaxConcurrencyStream          = RollingCommandMaxConcurrencyStream.GetInstance(key, properties);
        }
        internal static void Reset()
        {
            foreach (HystrixCommandMetrics metricsInstance in GetInstances())
            {
                metricsInstance.UnsubscribeAll();
            }

            RollingCommandEventCounterStream.Reset();
            CumulativeCommandEventCounterStream.Reset();
            RollingCommandLatencyDistributionStream.Reset();
            RollingCommandUserLatencyDistributionStream.Reset();
            RollingCommandMaxConcurrencyStream.Reset();
            HystrixThreadEventStream.Reset();
            HealthCountsStream.Reset();

            Metrics.Clear();
        }
        public void TestEmptyStreamProducesZeros()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-A");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 500);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(5).Subscribe(
                new LatchedObserver(output, latch));

            // no writes
            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");

            Assert.Equal(0, stream.LatestRollingMax);
        }
        public async void TestConcurrencyStreamProperlyFiltersOutSemaphoreRejections()
        {
            IHystrixCommandKey key   = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-H");
            CountdownEvent     latch = new CountdownEvent(1);
            var observer             = new LatchedObserver(output, latch);

            stream            = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            latchSubscription = stream.Observe().Subscribe(observer);
            Assert.True(Time.WaitUntil(() => observer.StreamRunning, 1000), "Stream failed to start");

            // 10 commands executed concurrently on different caller threads should saturate semaphore
            // once these are in-flight, execute 10 more concurrently on new caller threads.
            // since these are semaphore-rejected, the max concurrency should be 10
            List <Command> saturators = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                saturators.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 500, ExecutionIsolationStrategy.SEMAPHORE));
            }

            List <Command> rejected = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                rejected.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 0, ExecutionIsolationStrategy.SEMAPHORE));
            }

            List <Task> sattasks = new List <Task>();

            foreach (Command saturatingCmd in saturators)
            {
                sattasks.Add(Task.Run(() => saturatingCmd.Execute()));
            }

            await Task.Delay(50);

            foreach (Command rejectedCmd in rejected)
            {
                await Task.Run(() => rejectedCmd.Execute());
            }

            Task.WaitAll(sattasks.ToArray());
            Assert.True(WaitForLatchedObserverToUpdate(observer, 1, 500, output), "Latch took to long to update");
            Assert.Equal(10, stream.LatestRollingMax);
        }
        public void TestConcurrencyStreamProperlyFiltersOutThreadPoolRejections()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-I");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(GetSubscriber(output, latch));

            //10 commands executed concurrently should saturate the Hystrix threadpool
            //once these are in-flight, execute 10 more concurrently
            //since these are threadpool-rejected, the max concurrency should be 10

            List <Command> saturators = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                saturators.Add(Command.From(groupKey, key, HystrixEventType.SUCCESS, 400));
            }

            List <Command> rejected = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                rejected.Add(Command.From(groupKey, key, HystrixEventType.SUCCESS, 100));
            }

            foreach (Command saturatingCmd in saturators)
            {
                saturatingCmd.Observe();
            }

            Time.Wait(30);

            foreach (Command rejectedCmd in rejected)
            {
                rejectedCmd.Observe();
            }

            Assert.True(latch.Wait(10000));
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(10, stream.LatestRollingMax);
        }
        public void TestConcurrencyStreamProperlyFiltersOutThreadPoolRejections()
        {
            IHystrixCommandKey key   = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-I");
            CountdownEvent     latch = new CountdownEvent(1);
            var observer             = new LatchedObserver(output, latch);

            stream            = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            latchSubscription = stream.Observe().Subscribe(observer);
            Assert.True(Time.WaitUntil(() => observer.StreamRunning, 1000), "Stream failed to start");

            // 10 commands executed concurrently should saturate the Hystrix threadpool
            // once these are in-flight, execute 10 more concurrently
            // since these are threadpool-rejected, the max concurrency should be 10
            List <Command> saturators = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                saturators.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 400));
            }

            List <Command> rejected = new List <Command>();

            for (int i = 0; i < 10; i++)
            {
                rejected.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 100));
            }

            List <Task> tasks = new List <Task>();

            foreach (Command saturatingCmd in saturators)
            {
                tasks.Add(saturatingCmd.ExecuteAsync());
            }

            Time.Wait(30);

            foreach (Command rejectedCmd in rejected)
            {
                tasks.Add(rejectedCmd.ExecuteAsync());
            }

            Task.WaitAll(tasks.ToArray());
            Assert.True(WaitForLatchedObserverToUpdate(observer, 1, 500, output), "Latch took to long to update");
            Assert.Equal(10, stream.LatestRollingMax);
        }
        public void TestConcurrencyStreamProperlyFiltersOutShortCircuits()
        {
            IHystrixCommandKey key   = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-G");
            CountdownEvent     latch = new CountdownEvent(1);
            var observer             = new LatchedObserver(output, latch);

            stream            = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            latchSubscription = stream.Observe().Subscribe(observer);
            Assert.True(Time.WaitUntil(() => observer.StreamRunning, 1000), "Stream failed to start");

            // after 3 failures, next command should short-circuit.
            // to prove short-circuited commands don't contribute to concurrency, execute 3 FAILURES in the first bucket sequentially
            // then when circuit is open, execute 20 concurrent commands.  they should all get short-circuited, and max concurrency should be 1
            Command failure1 = Command.From(GroupKey, key, HystrixEventType.FAILURE);
            Command failure2 = Command.From(GroupKey, key, HystrixEventType.FAILURE);
            Command failure3 = Command.From(GroupKey, key, HystrixEventType.FAILURE);

            List <Command> shortCircuited = new List <Command>();

            for (int i = 0; i < 20; i++)
            {
                shortCircuited.Add(Command.From(GroupKey, key, HystrixEventType.SUCCESS, 0));
            }

            failure1.Execute();
            failure2.Execute();
            failure3.Execute();

            Assert.True(WaitForHealthCountToUpdate(key.Name, 500, output), "Health count stream update took to long");

            List <Task> tasks = new List <Task>();

            foreach (Command cmd in shortCircuited)
            {
                tasks.Add(cmd.ExecuteAsync());
            }

            Task.WaitAll(tasks.ToArray());
            Assert.True(WaitForLatchedObserverToUpdate(observer, 1, 500, output), "Latch took to long to update");

            Assert.Equal(1, stream.LatestRollingMax);
        }
        public void TestStartsAndEndsInSameBucketProduceValue()
        {
            IHystrixCommandKey key   = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-B");
            CountdownEvent     latch = new CountdownEvent(1);
            var observer             = new LatchedObserver(output, latch);

            stream            = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 500);
            latchSubscription = stream.Observe().Subscribe(observer);
            Assert.True(Time.WaitUntil(() => observer.StreamRunning, 2000), "Stream failed to start");

            Command cmd1 = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 100);
            Command cmd2 = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 100);

            Task t1 = cmd1.ExecuteAsync();
            Task t2 = cmd2.ExecuteAsync();

            Task.WaitAll(t1, t2);

            Assert.True(WaitForLatchedObserverToUpdate(observer, 1, 2000, output), "Latch took to long to update");
            Assert.Equal(2, stream.LatestRollingMax);
        }
        public void TestConcurrencyStreamProperlyFiltersOutShortCircuits()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-G");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(GetSubscriber(output, latch));

            //after 3 failures, next command should short-circuit.
            //to prove short-circuited commands don't contribute to concurrency, execute 3 FAILURES in the first bucket sequentially
            //then when circuit is open, execute 20 concurrent commands.  they should all get short-circuited, and max concurrency should be 1
            Command failure1 = Command.From(groupKey, key, HystrixEventType.FAILURE);
            Command failure2 = Command.From(groupKey, key, HystrixEventType.FAILURE);
            Command failure3 = Command.From(groupKey, key, HystrixEventType.FAILURE);

            List <Command> shortCircuited = new List <Command>();

            for (int i = 0; i < 20; i++)
            {
                shortCircuited.Add(Command.From(groupKey, key, HystrixEventType.SUCCESS, 100));
            }

            failure1.Execute();
            failure2.Execute();
            failure3.Execute();

            Time.Wait(150);

            foreach (Command cmd in shortCircuited)
            {
                cmd.Observe();
            }

            Assert.True(latch.Wait(10000));
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(1, stream.LatestRollingMax);
        }
        public void TestStartsAndEndsInSameBucketProduceValue()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-B");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 500);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(5).Subscribe(GetSubscriber(output, latch));

            Command cmd1 = Command.From(groupKey, key, HystrixEventType.SUCCESS, 100);
            Command cmd2 = Command.From(groupKey, key, HystrixEventType.SUCCESS, 100);

            cmd1.Observe();
            Time.Wait(1);

            cmd2.Observe();

            Assert.True(latch.Wait(10000));
            Assert.Equal(2, stream.LatestRollingMax);
        }
        public void TtestOneCommandCarriesOverToNextBucket()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-C");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 100);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(GetSubscriber(output, latch));

            Command cmd1 = Command.From(groupKey, key, HystrixEventType.SUCCESS, 160);
            Command cmd2 = Command.From(groupKey, key, HystrixEventType.SUCCESS, 10);
            Command cmd3 = Command.From(groupKey, key, HystrixEventType.SUCCESS, 15);

            cmd1.Observe();
            Time.Wait(100); //bucket roll
            cmd2.Observe();
            Time.Wait(1);
            cmd3.Observe();

            Assert.True(latch.Wait(10000));
            Assert.Equal(3, stream.LatestRollingMax);
        }
        public void TestEmptyStreamProducesZeros()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Concurrency-A");

            stream = RollingCommandMaxConcurrencyStream.GetInstance(key, 10, 500);
            stream.StartCachingStreamValuesIfUnstarted();

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(5).Subscribe(
                GetSubscriber(output, latch));

            //no writes

            try
            {
                Assert.True(latch.Wait(10000));
            }
            catch (Exception)
            {
                Assert.True(false, "Interrupted ex");
            }
            Assert.Equal(0, stream.LatestRollingMax);
        }