コード例 #1
0
        private static void AddSubscriptions(
            ICheckpointingQueryEngine engine,
            ConcurrentQueue <MockObservable <int> > inputs,
            int numberOfSubscriptions)
        {
            var reactive = GetQueryEngineReactiveService(engine);

            for (int i = 0; i < numberOfSubscriptions; i++)
            {
                var sourceUri       = new Uri(engine.Uri + "/source" + i);
                var source          = reactive.GetObservable <string, int>(MockObservableUri)(sourceUri.ToString());
                var subscriptionUri = new Uri(engine.Uri + "/subscription" + i);
                source.SubscribeOnScheduler().Subscribe(
                    reactive.GetObserver <string, int>(MockObserverUri)(sourceUri.ToString()),
                    subscriptionUri,
                    null);

                inputs.Enqueue(MockObservable.Get <int>(sourceUri.ToString()));
            }
        }
コード例 #2
0
        public void TwoQueryEnginesFirstFailAndRecover()
        {
            var qe1Id = "qe:/1/" + Guid.NewGuid();
            var qe2Id = "qe:/2/" + Guid.NewGuid();

            Uri sub = new Uri("bing:/sub1");

            IObserver <int>       o1s;
            MockObservable <int>  o1;
            MockObserver <int>    v1;
            IReactiveQubscription sub1;

            InMemoryStateStore store;

            CheckpointingQueryEngine qe1 = CreateQueryEngine(qe1Id);

            var ctx1 = GetQueryEngineReactiveService(qe1);

            var qe2 = CreateQueryEngine(qe2Id);

            var ctx2 = GetQueryEngineReactiveService(qe2);

            //
            // BUG: There's a known test bug here with the resolver not being smart enough to deal with a disposed
            //      upstream engine. When QE2 triggers disposal of the upstream subscription (after having sent 5
            //      events causing Take to reach OnCompleted and thus disposing its source), its InputEdge is faced
            //      with an external subscription into the original QE1 instance. If this instance got disposed by
            //      means of `using (qe1)`, an ObjectDisposedException will propagate out of QE1 into the Dispose
            //      path triggered inside QE2.
            //
            //      In a real setup, the resolver returns IReactive interface implementations that encapsulate a
            //      transport layer where failures are detected and re-resolution takes place if there's a broken
            //      channel. For this particular case, the original instance of QE1 having disappeared would result
            //      in such an error (e.g. having failed over to another node in a cluster).
            //
            //      For our test setup, we lack re-resolution logic, so disposing QE1 is problematic. One option is
            //      to rewrite the mock resolver to have proper failure detection. Alternatively, this test would
            //      have to be built on a more realistic setup (e.g. using the remoting stack).
            //

            //using (qe1)
            {
                AssertObservableNotCreated <int>("o1");
                AssertObserverNotCreated <int>("v1");

                ctx1.DefineObservable <int>(
                    new Uri(qe1Id + "/obs1"),
                    ctx1.GetObservable <string, int>(MockObservableUri)("o1").Where(x => x > 0).Take(10),
                    null);

                var obs1 = ctx1.GetObservable <int>(new Uri(qe1Id + "/obs1"));

                ctx2.DefineObservable <int>(
                    new Uri(qe2Id + "/obs2"),
                    obs1.Where(x => x % 2 == 1).Take(5),
                    null);

                var obs2 = ctx2.GetObservable <int>(new Uri(qe2Id + "/obs2"));

                sub1 = obs2.Subscribe(
                    ctx2.GetObserver <string, int>(MockObserverUri)("v1"), sub, null);

                o1 = MockObservable.Get <int>("o1");
                Assert.IsNotNull(o1);
                Assert.AreEqual(1, o1.SubscriptionCount);

                o1s = o1.Synchronize(qe1.Scheduler);

                v1 = GetMockObserver <int>("v1");

                for (int i = 0; i < 4; i++)
                {
                    o1s.OnNext(i);
                }

                Assert.IsTrue(v1.WaitForCount(2, Timeout));

                Assert.IsFalse(v1.Completed);
                Assert.IsFalse(v1.Error);

                AssertResult(v1, 2, (i, v) => Assert.AreEqual(i * 2 + 1, v));

                store = Checkpoint(qe1);
                RemoveQueryEngine(qe1);
            }

            o1.DropAllSubscriptions();
            Assert.AreEqual(0, o1.SubscriptionCount);

            qe1 = CreateQueryEngine(qe1Id);

            //using (qe1)
            {
                using (var stateReader = new InMemoryStateReader(store))
                {
                    qe1.RecoverAsync(stateReader).Wait();
                }

                Assert.AreEqual(1, o1.SubscriptionCount);

                o1s = o1.Synchronize(qe1.Scheduler);

                for (int i = 4; i < 20; i++)
                {
                    o1s.OnNext(i);
                }

                Assert.IsTrue(v1.WaitForCount(5, Timeout));
                Assert.IsTrue(v1.WaitForCompleted(Timeout));

                Assert.IsTrue(v1.Completed);
                Assert.IsFalse(v1.Error);

                sub1.Dispose();

                Assert.AreEqual(0, o1.SubscriptionCount);

                AssertResult(v1, 5, (i, v) => Assert.AreEqual(i * 2 + 1, v));
            }
        }
コード例 #3
0
        public void OneQueryTwoQueryEngines()
        {
            var qe1Id = "qe:/1/" + Guid.NewGuid();
            var qe2Id = "qe:/2/" + Guid.NewGuid();

            var qe1  = CreateQueryEngine(qe1Id);
            var ctx1 = GetQueryEngineReactiveService(qe1);

            var qe2  = CreateQueryEngine(qe2Id);
            var ctx2 = GetQueryEngineReactiveService(qe2);

            AssertObservableNotCreated <int>("o1");
            AssertObserverNotCreated <int>("v1");

            ctx1.DefineObservable <int>(
                new Uri(qe1Id + "/obs1"),
                ctx1.GetObservable <string, int>(MockObservableUri)("o1").Where(x => x > 0).Take(10),
                null);

            var obs1 = ctx1.GetObservable <int>(new Uri(qe1Id + "/obs1"));

            ctx2.DefineObservable <int>(
                new Uri(qe2Id + "/obs2"),
                obs1.Where(x => x % 2 == 1).Take(5),
                null);

            var obs2 = ctx2.GetObservable <int>(new Uri(qe2Id + "/obs2"));

            var sub1 = obs2.Subscribe(
                ctx2.GetObserver <string, int>(MockObserverUri)("v1"), new Uri(qe2Id + "/sub1"), null);

            var o1 = MockObservable.Get <int>("o1");

            Assert.IsNotNull(o1);
            Assert.AreEqual(1, o1.SubscriptionCount);

            var o1s = o1.Synchronize(qe1.Scheduler);

            var v1 = GetMockObserver <int>("v1");

            for (int i = 0; i < 4; i++)
            {
                o1s.OnNext(i);
            }

            Assert.IsTrue(v1.WaitForCount(2, Timeout));

            Assert.IsFalse(v1.Completed);
            Assert.IsFalse(v1.Error);

            o1s.OnCompleted();

            Assert.IsTrue(v1.WaitForCompleted(Timeout));
            Assert.IsFalse(v1.Error);

            sub1.Dispose();

            Assert.AreEqual(0, o1.SubscriptionCount);

            AssertResult(v1, 2, (i, v) => Assert.AreEqual(i * 2 + 1, v));
        }
コード例 #4
0
        public void TwoQueryEnginesSecondFailAndRecover()
        {
            var qe1Id = "qe:/1/" + Guid.NewGuid();
            var qe2Id = "qe:/2/" + Guid.NewGuid();

            Uri sub = new Uri("my:/sub1");

            IObserver <int>      o1s;
            MockObservable <int> o1;
            MockObserver <int>   v1;

            InMemoryStateStore store;

            var qe1 = CreateQueryEngine(qe1Id);
            {
                var ctx1 = GetQueryEngineReactiveService(qe1);

                var qe2 = CreateQueryEngine(qe2Id);
                {
                    var ctx2 = GetQueryEngineReactiveService(qe2);

                    AssertObservableNotCreated <int>("o1");
                    AssertObserverNotCreated <int>("v1");

                    ctx1.DefineObservable <int>(
                        new Uri(qe1Id + "/obs1"),
                        ctx1.GetObservable <string, int>(MockObservableUri)("o1").Where(x => x > 0).Take(10),
                        null);

                    var obs1 = ctx1.GetObservable <int>(new Uri(qe1Id + "/obs1"));

                    ctx2.DefineObservable <int>(
                        new Uri(qe2Id + "/obs2"),
                        obs1.Where(x => x % 2 == 1).Take(5),
                        null);

                    var obs2 = ctx2.GetObservable <int>(new Uri(qe2Id + "/obs2"));

                    var sub1 = obs2.Subscribe(
                        ctx2.GetObserver <string, int>(MockObserverUri)("v1"), sub, null);

                    o1 = MockObservable.Get <int>("o1");
                    Assert.IsNotNull(o1);
                    Assert.AreEqual(1, o1.SubscriptionCount);

                    o1s = o1.Synchronize(qe1.Scheduler);

                    v1 = GetMockObserver <int>("v1");

                    for (int i = 0; i < 4; i++)
                    {
                        o1s.OnNext(i);
                    }

                    Assert.IsTrue(v1.WaitForCount(2, Timeout));

                    Assert.IsFalse(v1.Completed);
                    Assert.IsFalse(v1.Error);

                    AssertResult(v1, 2, (i, v) => Assert.AreEqual(i * 2 + 1, v));

                    store = Checkpoint(qe2);
                    RemoveQueryEngine(qe2);
                }

                qe2 = CreateQueryEngine(qe2Id);
                {
                    var ctx2 = GetQueryEngineReactiveService(qe2);

                    using (var stateReader = new InMemoryStateReader(store))
                    {
                        qe2.RecoverAsync(stateReader).Wait();
                    }

                    var sub1 = ctx2.GetSubscription(sub);
                    Assert.IsNotNull(sub1);

                    for (int i = 4; i < 20; i++)
                    {
                        o1s.OnNext(i);
                    }

                    Assert.IsTrue(v1.WaitForCount(5, Timeout));

                    Assert.IsTrue(v1.Completed);
                    Assert.IsFalse(v1.Error);

                    sub1.Dispose();

                    Assert.AreEqual(0, o1.SubscriptionCount);

                    AssertResult(v1, 5, (i, v) => Assert.AreEqual(i * 2 + 1, v));
                }
            }
        }