Example #1
0
        public void ToJsonList_ReturnsExpected()
        {
            var            stream = HystrixDashboardStream.GetInstance();
            CountdownEvent latch  = new CountdownEvent(1);


            List <string> result       = null;
            var           subscription = stream.Observe()
                                         .SubscribeOn(NewThreadScheduler.Default)
                                         .ObserveOn(NewThreadScheduler.Default)
                                         .Subscribe(
                (data) =>
            {
                result = Serialize.ToJsonList(data, null);
                if (result.Count > 0)
                {
                    latch.SignalEx();
                }
            },
                (e) =>
            {
                latch.SignalEx();
            },
                () =>
            {
                latch.SignalEx();
            });


            MyCommand cmd = new MyCommand();

            cmd.Execute();

            latch.Wait(10000);

            Assert.NotNull(result);
            Assert.True(result.Count > 0);

            var jsonObject = result[0];

            var dict = JsonConvert.DeserializeObject <Dictionary <string, object> >(jsonObject);

            Assert.NotNull(dict);

            Assert.NotNull(dict["origin"]);
            Assert.NotNull(dict["data"]);
            JObject cmdData = (JObject)dict["data"];

            Assert.NotNull(cmdData["type"]);
            var type = cmdData["type"].Value <string>();

            Assert.True("HystrixCommand".Equals(type) || "HystrixThreadPool".Equals(type));
            Assert.NotNull(cmdData["name"]);
            var name = cmdData["name"].Value <string>();;

            Assert.True("MyCommand".Equals(name) || "MyCommandGroup".Equals(name));


            subscription.Dispose();
        }
Example #2
0
        public void TestTwoSubscribersOneSlowOneFast()
        {
            CountdownEvent latch      = new CountdownEvent(1);
            AtomicBoolean  foundError = new AtomicBoolean(false);

            IObservable <HystrixDashboardStream.DashboardData> fast = stream
                                                                      .Observe()
                                                                      .ObserveOn(NewThreadScheduler.Default);

            IObservable <HystrixDashboardStream.DashboardData> slow = stream
                                                                      .Observe()
                                                                      .ObserveOn(NewThreadScheduler.Default)
                                                                      .Map((n) =>
            {
                try
                {
                    Time.Wait(100);
                    return(n);
                }
                catch (Exception)
                {
                    return(n);
                }
            });

            IObservable <bool> checkZippedEqual = Observable.Zip(fast, slow, (payload, payload2) =>
            {
                return(payload == payload2);
            });

            IDisposable s1 = checkZippedEqual
                             .Take(10000)
                             .Subscribe(
                (b) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : OnNext : " + b);
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : OnError : " + e);
                output.WriteLine(e.ToString());
                foundError.Value = true;
                latch.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : OnCompleted");
                latch.SignalEx();
            });

            for (int i = 0; i < 50; i++)
            {
                HystrixCommand <int> cmd = Command.From(GroupKey, CommandKey, HystrixEventType.SUCCESS, 50);
                cmd.Execute();
            }

            latch.Wait(10000);
            Assert.False(foundError.Value);
            s1.Dispose();
        }
Example #3
0
        public void TestSharedSourceStream()
        {
            var key = HystrixCommandKeyDefault.AsKey("CMD-Health-N");

            stream = HealthCountsStream.GetInstance(key, 10, 100);

            var latch    = new CountdownEvent(1);
            var allEqual = new AtomicBoolean(false);

            var o1 = stream
                     .Observe()
                     .Take(10)
                     .ObserveOn(TaskPoolScheduler.Default);

            var o2 = stream
                     .Observe()
                     .Take(10)
                     .ObserveOn(TaskPoolScheduler.Default);

            var zipped = Observable.Zip(o1, o2, (healthCounts, healthCounts2) =>
            {
                return(healthCounts == healthCounts2);         // we want object equality
            });
            var reduced = zipped.Aggregate(true, (a, b) =>
            {
                return(a && b);
            }).Select(n => n);

            var rdisp = reduced.Subscribe(
                (b) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " Reduced OnNext : " + b);
                allEqual.Value = b;
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " Reduced OnError : " + e);
                output.WriteLine(e.ToString());
                latch.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " Reduced OnCompleted");
                latch.SignalEx();
            });

            for (var i = 0; i < 10; i++)
            {
                HystrixCommand <int> cmd = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 20);
                cmd.Execute();
            }

            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            Assert.True(allEqual.Value);

            rdisp.Dispose();

            // we should be getting the same object from both streams.  this ensures that multiple subscribers don't induce extra work
        }
        protected void AssertNonBlockingObserve(C command, Action <C> assertion, bool isSuccess)
        {
            //output.WriteLine("Running command.observe(), awaiting terminal state of Observable, then running assertions...");
            CountdownEvent latch = new CountdownEvent(1);

            IObservable <int> o = command.Observe();

            o.Subscribe(
                (n) =>
            {
            },
                (e) =>
            {
                latch.SignalEx();
            },
                () =>
            {
                latch.SignalEx();
            });

            try
            {
                latch.Wait(3000);
                assertion(command);
            }
            catch (Exception)
            {
                throw;
            }

            if (isSuccess)
            {
                try
                {
                    o.ToList().Single();
                }
                catch (Exception)
                {
                    throw;
                }
            }
            else
            {
                try
                {
                    o.ToList().Single();
                    Assert.True(false, "Expected a command failure!");
                }
                catch (Exception)
                {
                    //output.WriteLine("Received expected ex : " + ex);
                    // ex.printStackTrace();
                }
            }
        }
Example #5
0
        public void TestCurrentConcurrentExecutionCount()
        {
            String key = "cmd-metrics-C";

            HystrixCommandMetrics      metrics    = null;
            List <IObservable <bool> > cmdResults = new List <IObservable <bool> >();

            int NUM_CMDS = 8;

            for (int i = 0; i < NUM_CMDS; i++)
            {
                HystrixCommand <Boolean> cmd = new SuccessCommand(key, 900);
                if (metrics == null)
                {
                    metrics = cmd.metrics;
                }
                IObservable <bool> eagerObservable = cmd.Observe();
                cmdResults.Add(eagerObservable);
            }

            try
            {
                Time.Wait(200);
            }
            catch (Exception ie)
            {
                Assert.True(false, ie.Message);
            }
            output.WriteLine("ReqLog: " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(NUM_CMDS, metrics.CurrentConcurrentExecutionCount);

            CountdownEvent latch = new CountdownEvent(1);

            Observable.Merge(cmdResults).Subscribe(
                (n) =>
            {
            },
                (e) =>
            {
                output.WriteLine("Error duing command execution");
                output.WriteLine(e.ToString());
                latch.SignalEx();
            },
                () =>
            {
                output.WriteLine("All commands done");
                latch.SignalEx();
            });


            latch.Wait(10000);
            Assert.Equal(0, metrics.CurrentConcurrentExecutionCount);
        }
        protected void AssertNonBlockingObserve(C command, Action <C> assertion, bool isSuccess)
        {
            CountdownEvent latch = new CountdownEvent(1);

            IObservable <int> o = command.Observe();

            o.Subscribe(
                (n) =>
            {
            },
                (e) =>
            {
                latch.SignalEx();
            },
                () =>
            {
                latch.SignalEx();
            });

            try
            {
                latch.Wait(3000);
                assertion(command);
            }
            catch (Exception)
            {
                throw;
            }

            if (isSuccess)
            {
                try
                {
                    o.ToList().SingleAsync().Wait();
                }
                catch (Exception)
                {
                    throw;
                }
            }
            else
            {
                try
                {
                    o.ToList().SingleAsync().Wait();
                    Assert.True(false, "Expected a command failure!");
                }
                catch (Exception)
                {
                }
            }
        }
Example #7
0
        public void TestEmptyStreamProducesEmptyDistributions()
        {
            IHystrixCollapserKey key = HystrixCollapserKeyDefault.AsKey("Collapser-Batch-Size-A");

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Skip(10).Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                Assert.Equal(0, distribution.GetTotalCount());
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

            // no writes
            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            Assert.Equal(0, stream.Latest.GetTotalCount());
        }
        public void TestThreadPoolRejectedCommandDoesNotGetLatencyTracked()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-E");

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

            // 10 commands with latency should occupy the entire threadpool.  execute those, then wait for bucket to roll
            // next command should be a thread-pool rejection
            List <Command> commands = new List <Command>();

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                if (distribution.GetTotalCount() > 0)
                {
                    AssertBetween(200, 250, distribution.GetMean());
                }
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

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

            Command threadPoolRejected = Command.From(GroupKey, key, HystrixEventType.SUCCESS);

            try
            {
                Time.Wait(40);
                threadPoolRejected.Observe();
            }
            catch (Exception ie)
            {
                Assert.True(false, ie.Message);
            }

            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.Equal(10, stream.Latest.GetTotalCount());
            AssertBetween(200, 250, stream.LatestMean);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.True(threadPoolRejected.IsResponseThreadPoolRejected, "Response NOT ThreadPoolRejected as expected");
        }
        public void TestMultipleBucketsBothGetStored()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-H");

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                if (distribution.GetTotalCount() == 2)
                {
                    AssertBetween(55, 90, distribution.GetMean());
                }
                if (distribution.GetTotalCount() == 5)
                {
                    AssertBetween(60, 90, distribution.GetMean());
                }
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

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

            cmd1.Observe();
            cmd2.Observe();

            try
            {
                Time.Wait(500);
            }
            catch (Exception)
            {
                Assert.True(false, "Interrupted ex");
            }

            Command cmd3 = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 60);
            Command cmd4 = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 60);
            Command cmd5 = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 70);

            cmd3.Observe();
            cmd4.Observe();
            cmd5.Observe();

            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            AssertBetween(55, 90, stream.LatestMean);
            AssertBetween(10, 50, stream.GetLatestPercentile(0.0));
            AssertBetween(100, 150, stream.GetLatestPercentile(100.0));
        }
        public void TestShortCircuitedCommandDoesNotGetLatencyTracked()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-D");

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

            // 3 failures is enough to trigger short-circuit.  execute those, then wait for bucket to roll
            // next command should be a short-circuit
            List <Command> commands = new List <Command>();

            for (int i = 0; i < 3; i++)
            {
                commands.Add(Command.From(GroupKey, key, HystrixEventType.FAILURE, 0));
            }

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                AssertBetween(0, 30, distribution.GetMean());
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

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

            Command shortCircuit = Command.From(GroupKey, key, HystrixEventType.SUCCESS);

            try
            {
                Time.Wait(200);
                shortCircuit.Observe();
            }
            catch (Exception ie)
            {
                Assert.True(false, ie.Message);
            }

            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            Assert.Equal(3, stream.Latest.GetTotalCount());
            AssertBetween(0, 30, stream.LatestMean);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.True(shortCircuit.IsResponseShortCircuited);
        }
        public void TestSingleBucketWithMultipleEventTypes()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-C");

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + DateTime.Now.Ticks / 10000 + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                if (distribution.GetTotalCount() < 4 && distribution.GetTotalCount() > 0)
                { //buckets before timeout latency registers
                    AssertBetween(10, 50, (int)distribution.GetMean());
                }
                else if (distribution.GetTotalCount() == 4)
                {
                    AssertBetween(150, 250, (int)distribution.GetMean()); //now timeout latency of 600ms is there
                }
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });



            Command cmd1 = Command.From(groupKey, key, HystrixEventType.SUCCESS, 10);
            Command cmd2 = Command.From(groupKey, key, HystrixEventType.TIMEOUT); //latency = 600
            Command cmd3 = Command.From(groupKey, key, HystrixEventType.FAILURE, 30);
            Command cmd4 = Command.From(groupKey, key, HystrixEventType.BAD_REQUEST, 40);

            cmd1.Observe();
            cmd2.Observe();
            cmd3.Observe();
            cmd4.Observe();

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

            AssertBetween(150, 350, stream.LatestMean); //now timeout latency of 600ms is there
            AssertBetween(10, 40, stream.GetLatestPercentile(0.0));
            AssertBetween(600, 800, stream.GetLatestPercentile(100.0));
        }
        public void TestStreamHasData()
        {
            AtomicBoolean  commandShowsUp    = new AtomicBoolean(false);
            AtomicBoolean  threadPoolShowsUp = new AtomicBoolean(false);
            CountdownEvent latch             = new CountdownEvent(1);
            int            num = 10;

            for (int i = 0; i < 2; i++)
            {
                HystrixCommand <int> cmd = Command.From(GroupKey, CommandKey, HystrixEventType.SUCCESS, 50);
                cmd.Observe();
            }

            stream.Observe().Take(num).Subscribe(
                (configuration) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Received data with : " + configuration.CommandConfig.Count + " commands");
                if (configuration.CommandConfig.ContainsKey(CommandKey))
                {
                    commandShowsUp.Value = true;
                }

                if (configuration.ThreadPoolConfig.Count != 0)
                {
                    threadPoolShowsUp.Value = true;
                }
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " OnError : " + e);
                latch.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " OnCompleted");
                latch.SignalEx();
            });

            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            Assert.True(commandShowsUp.Value);
            Assert.True(threadPoolShowsUp.Value);
        }
        public void TestStreamHasData()
        {
            AtomicBoolean  commandShowsUp    = new AtomicBoolean(false);
            AtomicBoolean  threadPoolShowsUp = new AtomicBoolean(false);
            CountdownEvent latch             = new CountdownEvent(1);
            int            NUM = 10;

            for (int i = 0; i < 2; i++)
            {
                HystrixCommand <int> cmd = Command.From(groupKey, commandKey, HystrixEventType.SUCCESS, 50);
                cmd.Observe();
            }

            stream.Observe().Take(NUM).Subscribe(
                (utilization) =>
            {
                output.WriteLine(DateTime.Now.Ticks / 10000 + " : Received data with : " + " : Received data with : " + utilization.CommandUtilizationMap.Count + " commands");
                if (utilization.CommandUtilizationMap.ContainsKey(commandKey))
                {
                    commandShowsUp.Value = true;
                }
                if (utilization.ThreadPoolUtilizationMap.Count != 0)
                {
                    threadPoolShowsUp.Value = true;
                }
            },
                (e) =>
            {
                output.WriteLine(DateTime.Now.Ticks / 10000 + " : " + Thread.CurrentThread.ManagedThreadId + " OnError : " + e);
                latch.SignalEx();
            },
                () =>
            {
                output.WriteLine(DateTime.Now.Ticks / 10000 + " : " + Thread.CurrentThread.ManagedThreadId + " OnCompleted");
                latch.SignalEx();
            });


            Assert.True(latch.Wait(10000));
            Assert.True(commandShowsUp.Value);
            Assert.True(threadPoolShowsUp.Value);
        }
        public void TestThreadSafety()
        {
            var time = new MockedTime();
            var p    = new HystrixRollingPercentile(time, 100, 25, 1000, true);

            int num_threads    = 1000; // .NET Core StackOverflow
            int num_iterations = 1000000;

            var latch = new CountdownEvent(num_threads);

            var aggregateMetrics = new AtomicInteger(); // same as a blackhole

            var r             = new Random();
            var cts           = new CancellationTokenSource();
            var metricsPoller = Task.Run(() =>
            {
                while (!cts.Token.IsCancellationRequested)
                {
                    aggregateMetrics.AddAndGet(p.Mean + p.GetPercentile(10) + p.GetPercentile(50) + p.GetPercentile(90));
                }
            });

            for (int i = 0; i < num_threads; i++)
            {
                int threadId = i;
                Task.Run(() =>
                {
                    for (int j = 1; j < (num_iterations / num_threads) + 1; j++)
                    {
                        int nextInt = r.Next(100);
                        p.AddValue(nextInt);
                        if (threadId == 0)
                        {
                            time.Increment(1);
                        }
                    }

                    latch.SignalEx();
                });
            }

            try
            {
                latch.Wait(TimeSpan.FromSeconds(100));
                cts.Cancel();
            }
            catch (Exception)
            {
                Assert.True(false, "Timeout on all threads writing percentiles");
            }

            aggregateMetrics.AddAndGet(p.Mean + p.GetPercentile(10) + p.GetPercentile(50) + p.GetPercentile(90));
            output.WriteLine(p.Mean + " : " + p.GetPercentile(50) + " : " + p.GetPercentile(75) + " : " + p.GetPercentile(90) + " : " + p.GetPercentile(95) + " : " + p.GetPercentile(99));
        }
Example #15
0
        public void TestSingleBucketGetsStored()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-B");

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                if (distribution.GetTotalCount() == 1)
                {
                    AssertBetween(10, 50, (int)distribution.GetMean());
                }
                else if (distribution.GetTotalCount() == 2)
                {
                    AssertBetween(300, 400, (int)distribution.GetMean());
                }
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

            Command cmd1 = Command.From(GroupKey, key, HystrixEventType.SUCCESS, 10);
            Command cmd2 = Command.From(GroupKey, key, HystrixEventType.TIMEOUT); // latency = 600

            cmd1.Observe();
            cmd2.Observe();

            try
            {
                Assert.True(latch.Wait(10000));
                output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            }
            catch (Exception)
            {
                output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
                Assert.True(false, "Interrupted ex");
            }

            AssertBetween(150, 400, stream.LatestMean);
            AssertBetween(10, 50, stream.GetLatestPercentile(0.0));
            AssertBetween(300, 800, stream.GetLatestPercentile(100.0));
        }
Example #16
0
        public void TestResponseFromCacheDoesNotGetLatencyTracked()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-G");

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

            // should get 1 SUCCESS and 1 RESPONSE_FROM_CACHE
            List <Command> commands = Command.GetCommandsWithResponseFromCache(GroupKey, key);

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                Assert.True(distribution.GetTotalCount() <= 1);
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

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

            try
            {
                Assert.True(latch.Wait(10000));
            }
            catch (Exception)
            {
                Assert.False(true, "Interrupted ex");
            }

            Assert.Equal(1, stream.Latest.GetTotalCount());
            AssertBetween(0, 30, stream.LatestMean);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
        }
        public void TestWriteThreadSafety()
        {
            var time = new MockedTime();
            var p    = new HystrixRollingPercentile(time, 100, 25, 1000, true);

            int num_threads    = 10;
            int num_iterations = 1000;

            var latch = new CountdownEvent(num_threads);

            var r = new Random();

            var added = new AtomicInteger(0);

            for (int i = 0; i < num_threads; i++)
            {
                var t = new Task(
                    () =>
                {
                    for (int j = 1; j < (num_iterations / num_threads) + 1; j++)
                    {
                        int nextInt = r.Next(100);
                        p.AddValue(nextInt);
                        added.GetAndIncrement();
                    }

                    latch.SignalEx();
                },
                    CancellationToken.None,
                    TaskCreationOptions.LongRunning);
                t.Start();
            }

            try
            {
                latch.Wait(TimeSpan.FromSeconds(100));
                Assert.Equal(added.Value, p._buckets.PeekLast._data.Length);
            }
            catch (Exception)
            {
                Assert.True(false, "Timeout on all threads writing percentiles");
            }
        }
Example #18
0
        public void TestStreamHasData()
        {
            AtomicBoolean  commandShowsUp = new AtomicBoolean(false);
            CountdownEvent latch          = new CountdownEvent(1);
            int            NUM            = 10;

            for (int i = 0; i < 2; i++)
            {
                HystrixCommand <int> cmd = Command.From(groupKey, commandKey, HystrixEventType.SUCCESS, 50);
                cmd.Observe();
            }

            stream.Observe().Take(NUM).Subscribe(
                (dashboardData) =>
            {
                output.WriteLine(DateTime.Now.Ticks / 10000 + " : Received data with : " + dashboardData.commandMetrics.Count + " commands");
                foreach (HystrixCommandMetrics metrics in dashboardData.commandMetrics)
                {
                    if (metrics.CommandKey.Equals(commandKey))
                    {
                        commandShowsUp.Value = true;
                    }
                }
            },
                (e) =>
            {
                output.WriteLine(DateTime.Now.Ticks / 10000 + " : " + Thread.CurrentThread.ManagedThreadId + " OnError : " + e);
            },
                () =>
            {
                output.WriteLine(DateTime.Now.Ticks / 10000 + " : " + Thread.CurrentThread.ManagedThreadId + " OnCompleted");
                latch.SignalEx();
            });



            Assert.True(latch.Wait(10000));
            Assert.True(commandShowsUp.Value);
        }
        public void TestEmptyStreamProducesEmptyDistributions()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-A");

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + DateTime.Now.Ticks / 10000 + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + Thread.CurrentThread.ManagedThreadId);
                Assert.Equal(0, distribution.GetTotalCount());
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });



            //no writes

            try
            {
                Assert.True(latch.Wait(10000));
            }
            catch (Exception)
            {
                Assert.True(false, "Interrupted ex");
            }
            Assert.Equal(0, stream.Latest.GetTotalCount());
        }
        public void TestStreamHasData()
        {
            var commandShowsUp = new AtomicBoolean(false);
            var latch          = new CountdownEvent(1);
            var num            = 10;

            for (var i = 0; i < 2; i++)
            {
                HystrixCommand <int> cmd = Command.From(GroupKey, CommandKey, HystrixEventType.SUCCESS, 50);
                cmd.Observe();
            }

            stream.Observe().Take(num).Subscribe(
                (dashboardData) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : Received data with : " + dashboardData.CommandMetrics.Count + " commands");
                foreach (var metrics in dashboardData.CommandMetrics)
                {
                    if (metrics.CommandKey.Equals(CommandKey))
                    {
                        commandShowsUp.Value = true;
                    }
                }
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " OnError : " + e);
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " OnCompleted");
                latch.SignalEx();
            });

            Assert.True(latch.Wait(10000), "CountdownEvent was not set!");
            Assert.True(commandShowsUp.Value);
        }
 protected override void OnCompletedCore()
 {
     output.WriteLine("OnCompletedCore @ " + DateTime.Now.Ticks / 10000 + " : " + Thread.CurrentThread.ManagedThreadId);
     latch.SignalEx();
 }
Example #22
0
        public void TestTwoSubscribersOneUnsubscribes()
        {
            CountdownEvent latch1    = new CountdownEvent(1);
            CountdownEvent latch2    = new CountdownEvent(1);
            AtomicInteger  payloads1 = new AtomicInteger(0);
            AtomicInteger  payloads2 = new AtomicInteger(0);

            IDisposable s1 = stream
                             .Observe()
                             .Take(100)
                             .OnDispose(() =>
            {
                latch1.SignalEx();
            })
                             .Subscribe(
                (dashboardData) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 1 OnNext : " + dashboardData);
                payloads1.IncrementAndGet();
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 1 OnError : " + e);
                latch1.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 1 OnCompleted");
                latch1.SignalEx();
            });

            IDisposable s2 = stream
                             .Observe()
                             .Take(100)
                             .OnDispose(() =>
            {
                latch2.SignalEx();
            })
                             .Subscribe(
                (dashboardData) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 2 OnNext : " + dashboardData);
                payloads2.IncrementAndGet();
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 2 OnError : " + e);
                latch2.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 2 OnCompleted");
                latch2.SignalEx();
            });

            // execute 1 command, then unsubscribe from first stream. then execute the rest
            for (int i = 0; i < 50; i++)
            {
                HystrixCommand <int> cmd = Command.From(GroupKey, CommandKey, HystrixEventType.SUCCESS, 50);
                cmd.Execute();
                if (i == 1)
                {
                    s1.Dispose();
                }
            }

            Assert.True(latch1.Wait(10000));
            Assert.True(latch2.Wait(10000));
            output.WriteLine("s1 got : " + payloads1.Value + ", s2 got : " + payloads2.Value);
            Assert.True(payloads1.Value > 0);               // "s1 got data"
            Assert.True(payloads2.Value > 0);               // "s2 got data"
            Assert.True(payloads2.Value > payloads1.Value); // "s1 got less data than s2",
        }
Example #23
0
        public void TestSemaphoreRejectedCommandDoesNotGetLatencyTracked()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Latency-F");

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

            // 10 commands with latency should occupy all semaphores.  execute those, then wait for bucket to roll
            // next command should be a semaphore rejection
            List <Command> commands = new List <Command>();

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
                if (distribution.GetTotalCount() > 0)
                {
                    AssertBetween(200, 250, (int)distribution.GetMean());
                }
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

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

            Command semaphoreRejected = Command.From(GroupKey, key, HystrixEventType.SUCCESS);

            try
            {
                Time.Wait(40);
                semaphoreRejected.Observe();
            }
            catch (Exception ie)
            {
                Assert.True(false, ie.Message);
            }

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

            Assert.Equal(10, stream.Latest.GetTotalCount());
            AssertBetween(200, 250, stream.LatestMean);
            output.WriteLine("ReqLog : " + HystrixRequestLog.CurrentRequestLog.GetExecutedCommandsAsString());
            Assert.True(semaphoreRejected.IsResponseSemaphoreRejected);
        }
Example #24
0
        public void TestTwoSubscribersBothUnsubscribe()
        {
            CountdownEvent latch1    = new CountdownEvent(1);
            CountdownEvent latch2    = new CountdownEvent(1);
            AtomicInteger  payloads1 = new AtomicInteger(0);
            AtomicInteger  payloads2 = new AtomicInteger(0);

            IDisposable s1 = stream
                             .Observe()
                             .Take(10)
                             .OnDispose(() =>
            {
                latch1.SignalEx();
            })
                             .Subscribe(
                (dashboardData) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 1 OnNext : " + dashboardData);
                payloads1.IncrementAndGet();
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 1 OnError : " + e);
                latch1.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 1 OnCompleted");
                latch1.SignalEx();
            });

            IDisposable s2 = stream
                             .Observe()
                             .Take(10)
                             .OnDispose(() =>
            {
                latch2.SignalEx();
            })
                             .Subscribe(
                (dashboardData) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 2 OnNext : " + dashboardData);
                payloads2.IncrementAndGet();
            },
                (e) =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 2 OnError : " + e);
                latch2.SignalEx();
            },
                () =>
            {
                output.WriteLine(Time.CurrentTimeMillis + " : " + Thread.CurrentThread.ManagedThreadId + " : Dashboard 2 OnCompleted");
                latch2.SignalEx();
            });

            // execute half the commands, then unsubscribe from both streams, then execute the rest
            for (int i = 0; i < 50; i++)
            {
                HystrixCommand <int> cmd = Command.From(GroupKey, CommandKey, HystrixEventType.SUCCESS, 50);
                cmd.Execute();
                if (i == 25)
                {
                    s1.Dispose();
                    s2.Dispose();
                }
            }

            Assert.False(stream.IsSourceCurrentlySubscribed);  // both subscriptions have been cancelled - source should be too

            Assert.True(latch1.Wait(10000));
            Assert.True(latch2.Wait(10000));
            output.WriteLine("s1 got : " + payloads1.Value + ", s2 got : " + payloads2.Value);
            Assert.True(payloads1.Value > 0); // "s1 got data",
            Assert.True(payloads2.Value > 0); // "s2 got data",
        }
Example #25
0
        public void TestTwoSubscribersOneUnsubscribes()
        {
            IHystrixCommandKey key = HystrixCommandKeyDefault.AsKey("CMD-Health-O");

            stream = HealthCountsStream.GetInstance(key, 10, 100);

            CountdownEvent latch1        = new CountdownEvent(1);
            CountdownEvent latch2        = new CountdownEvent(1);
            AtomicInteger  healthCounts1 = new AtomicInteger(0);
            AtomicInteger  healthCounts2 = new AtomicInteger(0);

            IDisposable s1 = stream
                             .Observe()
                             .Take(10)
                             .ObserveOn(TaskPoolScheduler.Default)
                             .Finally(() =>
            {
                latch1.SignalEx();
            })
                             .Subscribe(
                (healthCounts) =>
            {
                output.WriteLine((DateTime.Now.Ticks / 10000) + " : " + Thread.CurrentThread.ManagedThreadId + " : Health 1 OnNext : " + healthCounts);
                healthCounts1.IncrementAndGet();
            },
                (e) =>
            {
                output.WriteLine((DateTime.Now.Ticks / 10000) + " : " + Thread.CurrentThread.ManagedThreadId + " : Health 1 OnError : " + e);
                latch1.SignalEx();
            },
                () =>
            {
                output.WriteLine((DateTime.Now.Ticks / 10000) + " : " + Thread.CurrentThread.ManagedThreadId + " : Health 1 OnCompleted");
                latch1.SignalEx();
            });
            IDisposable s2 = stream
                             .Observe()
                             .Take(10)
                             .ObserveOn(TaskPoolScheduler.Default)
                             .Finally(() =>
            {
                latch2.SignalEx();
            })
                             .Subscribe(
                (healthCounts) =>
            {
                output.WriteLine((DateTime.Now.Ticks / 10000) + " : " + Thread.CurrentThread.ManagedThreadId + " : Health 2 OnNext : " + healthCounts + " : " + healthCounts2.Value);
                healthCounts2.IncrementAndGet();
            },
                (e) =>
            {
                output.WriteLine((DateTime.Now.Ticks / 10000) + " : " + Thread.CurrentThread.ManagedThreadId + " : Health 2 OnError : " + e);
                latch2.SignalEx();
            },
                () =>
            {
                output.WriteLine((DateTime.Now.Ticks / 10000) + " : " + Thread.CurrentThread.ManagedThreadId + " : Health 2 OnCompleted");
                latch2.SignalEx();
            });

            // execute 5 commands, then unsubscribe from first stream. then execute the rest
            for (int i = 0; i < 10; i++)
            {
                HystrixCommand <int> cmd = Command.From(groupKey, key, HystrixEventType.SUCCESS, 20);
                cmd.Execute();
                if (i == 5)
                {
                    s1.Dispose();
                }
            }

            Assert.True(stream.IsSourceCurrentlySubscribed);  // only 1/2 subscriptions has been cancelled

            Assert.True(latch1.Wait(10000));
            Assert.True(latch2.Wait(10000));
            output.WriteLine("s1 got : " + healthCounts1.Value + ", s2 got : " + healthCounts2.Value);
            Assert.True(healthCounts1.Value > 0);
            Assert.True(healthCounts2.Value > 0);
            Assert.True(healthCounts2.Value > healthCounts1.Value);
        }
Example #26
0
 protected override void OnCompletedCore()
 {
     output.WriteLine("OnCompleted @ " + (DateTime.Now.Ticks / 10000));
     latch.SignalEx();
 }
 protected override void OnCompletedCore()
 {
     latch.SignalEx();
 }
 protected override void OnCompletedCore()
 {
     output?.WriteLine("OnComplete @ " + Time.CurrentTimeMillis + " :" + Thread.CurrentThread.ManagedThreadId);
     StreamRunning = false;
     latch.SignalEx();
 }
Example #29
0
        public void TestBatches()
        {
            IHystrixCollapserKey key = HystrixCollapserKeyDefault.AsKey("Collapser-Batch-Size-B");

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

            CountdownEvent latch = new CountdownEvent(1);

            stream.Observe().Take(10).Subscribe(
                (distribution) =>
            {
                output.WriteLine("OnNext @ " + (DateTime.Now.Ticks / 10000) + " : " + distribution.GetMean() + "/" + distribution.GetTotalCount() + " " + Thread.CurrentThread.ManagedThreadId);
            },
                (e) =>
            {
                Assert.True(false, e.Message);
            },
                () =>
            {
                latch.SignalEx();
            });

            Collapser.From(output, key, 1).Observe();
            Collapser.From(output, key, 2).Observe();
            Collapser.From(output, key, 3).Observe();

            try
            {
                Time.Wait(250);
            }
            catch (Exception)
            {
                Assert.False(true, "Interrupted ex");
            }

            Collapser.From(output, key, 4).Observe();

            try
            {
                Time.Wait(250);
            }
            catch (Exception)
            {
                Assert.False(true, "Interrupted ex");
            }

            Collapser.From(output, key, 5).Observe();
            Collapser.From(output, key, 6).Observe();
            Collapser.From(output, key, 7).Observe();
            Collapser.From(output, key, 8).Observe();
            Collapser.From(output, key, 9).Observe();

            try
            {
                Time.Wait(250);
            }
            catch (Exception)
            {
                Assert.False(true, "Interrupted ex");
            }

            Collapser.From(output, key, 10).Observe();
            Collapser.From(output, key, 11).Observe();
            Collapser.From(output, key, 12).Observe();

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

            // should have 4 batches: 3, 1, 5, 3
            Assert.Equal(4, stream.Latest.GetTotalCount());
            Assert.Equal(3, stream.LatestMean);
            Assert.Equal(1, stream.GetLatestPercentile(0));
            Assert.Equal(5, stream.GetLatestPercentile(100));
        }