public void Activate_is_not_called_more_than_once_during_concurrent_calls_when_activator_has_no_dependencies()
        {
            var activations   = 0;
            var notifications = 0;
            var barrier       = new Barrier(2);

            var activator = new FeatureActivator(() =>
            {
                Interlocked.Increment(ref activations);
                barrier.SignalAndWait();
            });

            for (var i = 0; i < 10; i++)
            {
                disposables.Add(activator
                                .ObserveOn(NewThreadScheduler.Default)
                                .SubscribeOn(NewThreadScheduler.Default)
                                .Subscribe(n =>
                {
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                    Interlocked.Increment(ref notifications);
                }));
            }

            // give both subscribers enough time to make sure one has advanced to the activator barrier
            Thread.Sleep(500);
            barrier.SignalAndWait();
            // give them enough time to propagate their notifications
            Thread.Sleep(500);

            Assert.That(activations, Is.EqualTo(1));
            Assert.That(notifications, Is.EqualTo(10));
        }
        public void Activate_is_not_called_more_than_once_during_concurrent_calls_when_activator_has_dependencies()
        {
            var activations   = 0;
            var notifications = 0;
            var barrier       = new Barrier(2);
            var subject       = new BehaviorSubject <bool>(false);

            var activator = new FeatureActivator(() =>
            {
                Console.WriteLine("activated!");
                Interlocked.Increment(ref activations);
                barrier.SignalAndWait();
            }, dependsOn: subject);

            for (var i = 0; i < 10; i++)
            {
                disposables.Add(activator
                                .ObserveOn(NewThreadScheduler.Default)
                                .SubscribeOn(NewThreadScheduler.Default)
                                .Subscribe(n =>
                {
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                    Interlocked.Increment(ref notifications);
                }));
            }

            new Thread(() => subject.OnNext(true)).Start();

            // give both subscribers enough time to make sure one has advanced to the activator barrier
            Thread.Sleep(1000);
            barrier.SignalAndWait(3000);
            // give them enough time to propagate their notifications
            Thread.Sleep(1000);

            Assert.That(notifications, Is.AtLeast(10)); // sanity check
            Assert.That(activations, Is.EqualTo(1));
        }
        public void Activate_is_not_called_more_than_once_during_concurrent_calls_when_activator_has_no_dependencies()
        {
            var activations = 0;
            var notifications = 0;
            var barrier = new Barrier(2);

            var activator = new FeatureActivator(() =>
            {
                Interlocked.Increment(ref activations);
                barrier.SignalAndWait();
            });

            for (var i = 0; i < 10; i++)
            {
                disposables.Add(activator
                                    .ObserveOn(NewThreadScheduler.Default)
                                    .SubscribeOn(NewThreadScheduler.Default)
                                    .Subscribe(n =>
                                    {
                                        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                                        Interlocked.Increment(ref notifications);
                                    }));
            }

            // give both subscribers enough time to make sure one has advanced to the activator barrier
            Thread.Sleep(500);
            barrier.SignalAndWait();
            // give them enough time to propagate their notifications
            Thread.Sleep(500);

            Assert.That(activations, Is.EqualTo(1));
            Assert.That(notifications, Is.EqualTo(10));
        }
        public void Activate_is_not_called_more_than_once_during_concurrent_calls_when_activator_has_dependencies()
        {
            var activations = 0;
            var notifications = 0;
            var barrier = new Barrier(2);
            var subject = new BehaviorSubject<bool>(false);

            var activator = new FeatureActivator(() =>
            {
                Console.WriteLine("activated!");
                Interlocked.Increment(ref activations);
                barrier.SignalAndWait();
            }, dependsOn: subject);

            for (var i = 0; i < 10; i++)
            {
                disposables.Add(activator
                                    .ObserveOn(NewThreadScheduler.Default)
                                    .SubscribeOn(NewThreadScheduler.Default)
                                    .Subscribe(n =>
                                    {
                                        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                                        Interlocked.Increment(ref notifications);
                                    }));
            }

            new Thread(() => subject.OnNext(true)).Start();

            // give both subscribers enough time to make sure one has advanced to the activator barrier
            Thread.Sleep(1000);
            barrier.SignalAndWait(3000);
            // give them enough time to propagate their notifications
            Thread.Sleep(1000);

            Assert.That(notifications, Is.AtLeast(10)); // sanity check
            Assert.That(activations, Is.EqualTo(1));
        }