public void StatefulOperator_Versioning_NotSupportedByDefault()
        {
            var o = Observer.Create <int>(_ => { }, _ => Assert.Fail(), () => Assert.Fail());

            var state         = new MockOperatorStateContainer();
            var writerFactory = state.CreateWriter();
            var readerFactory = state.CreateReader();

            var mo = new MyOperator(o)
            {
                State = 42
            };

            mo.Start();

            var writer = writerFactory.Create(mo);

            Assert.ThrowsException <NotSupportedException>(() => mo.SaveState(writer, new Version(2, 0, 0, 0)));

            var mor = new MyOperator(o);

            var reader = readerFactory.Create(mor);

            Assert.ThrowsException <NotSupportedException>(() => mor.LoadState(reader, new Version(2, 0, 0, 0)));
        }
        public void Engine_Subject_Checkpoint_Empty()
        {
            var id  = new Uri("tests://bar/foo");
            var svc = new MiniService();

            var mosc = new MockOperatorStateContainer();

            {
                var subject = GetSubject(id, svc);
                subject.Seal();

                Assert.IsTrue(subject.StateChanged);

                using (var oswf = mosc.CreateWriter())
                {
                    oswf.SaveState(subject);
                }

                Assert.IsTrue(subject.StateChanged);

                subject.OnStateSaved();

                Assert.IsFalse(subject.StateChanged);
            }

            {
                var subject = GetSubject(id, svc);

                Assert.IsTrue(subject.StateChanged);

                using (var osrf = mosc.CreateReader())
                {
                    osrf.LoadState(subject);
                }

                Assert.IsFalse(subject.StateChanged);

                // gets sealed immediately upon recovery because it was empty
                Assert.ThrowsException <InvalidOperationException>(() => subject.Subscribe(Observer.Nop <int>()));
            }
        }
Example #3
0
        public void SubscriptionStateVisitor_Basics()
        {
            var state         = new MockOperatorStateContainer();
            var writerFactory = state.CreateWriter();
            var readerFactory = state.CreateReader();

            var xs = new SimpleSubject <int>();
            var o  = xs.CreateObserver();

            var ys = new Take <int>(xs, 5);

            {
                var s1 = ys.Subscribe(Observer.Create <int>(_ => { }, _ => { }, () => { }));
                var v  = new SubscriptionInitializeVisitor(s1);
                v.Subscribe();
                v.Start();

                o.OnNext(42);
                o.OnNext(43);

                var sv = new SubscriptionStateVisitor(s1);

                Assert.IsTrue(sv.HasStateChanged());

                sv.SaveState(writerFactory);

                Assert.IsTrue(sv.HasStateChanged());

                sv.OnStateSaved();

                Assert.IsFalse(sv.HasStateChanged());

                o.OnNext(44);
                o.OnNext(45);

                Assert.IsTrue(sv.HasStateChanged());
            }

            {
                var done = false;

                var s2 = ys.Subscribe(Observer.Create <int>(_ => { }, _ => { }, () => { done = true; }));

                var sv = new SubscriptionStateVisitor(s2);

                sv.LoadState(readerFactory);

                var v = new SubscriptionInitializeVisitor(s2);
                v.Subscribe();
                v.Start();

                o.OnNext(46);
                Assert.IsFalse(done);

                o.OnNext(47);
                Assert.IsFalse(done);

                o.OnNext(48);
                Assert.IsTrue(done);
            }
        }
        public void StatefulObserver_State()
        {
            var state         = new MockOperatorStateContainer();
            var writerFactory = state.CreateWriter();
            var readerFactory = state.CreateReader();

            var mo = new MyObserver()
            {
                State = 42
            };

            mo.Start();
            Assert.IsTrue(mo.Started);
            Assert.IsTrue(mo.StateChanged);

            Assert.ThrowsException <ArgumentNullException>(() => mo.SaveState(null, mo.Version));

            var writer = writerFactory.Create(mo);

            mo.SaveState(writer, mo.Version);

            Assert.IsTrue(mo.StateChanged);
            mo.OnStateSaved();
            Assert.IsFalse(mo.StateChanged);

            var mor = new MyObserver();

            var reader = readerFactory.Create(mor);

            Assert.ThrowsException <ArgumentNullException>(() => mor.LoadState(null, mor.Version));

            mor.LoadState(reader, mor.Version);

            mor.Start();
            Assert.IsTrue(mor.Started);

            Assert.AreEqual(42, mor.State);

            mo.State = 43;
            Assert.IsTrue(mo.StateChanged);

            writer = writerFactory.Create(mo);
            mo.SaveState(writer, mo.Version);
            mo.OnStateSaved();
            Assert.IsFalse(mo.StateChanged);

            var moq = new MyObserver();

            reader = readerFactory.Create(moq);
            moq.LoadState(reader, moq.Version);

            moq.Start();
            Assert.IsTrue(moq.Started);

            Assert.AreEqual(43, moq.State);

            mo.Dispose();

            Assert.IsTrue(mo.Disposed);

            writer = writerFactory.Create(mo);
            mo.SaveState(writer, mo.Version);
            mo.OnStateSaved();

            var mop = new MyObserver();

            reader = readerFactory.Create(mop);
            mop.LoadState(reader, mop.Version);
            mop.Start();

            Assert.IsTrue(mop.Disposed);
            Assert.IsFalse(mop.Started);
        }
        public void Engine_Subject_Checkpoint_SealLater()
        {
            var id  = new Uri("tests://bar/foo");
            var svc = new MiniService();
            var sch = new MiniScheduler();

            var mosc1 = new MockOperatorStateContainer();
            var mosc2 = new MockOperatorStateContainer();

            {
                var subject = GetSubject(id, svc);

                var xs = (ISubscribable <int>)subject;

                var d1 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d1).Initialize(CreateOperatorContext(new Uri("tests://qux/1"), svc, sch));

                var d2 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d2).Initialize(CreateOperatorContext(new Uri("tests://qux/2"), svc, sch));

                d1.Dispose();

                var d3 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d3).Initialize(CreateOperatorContext(new Uri("tests://qux/3"), svc, sch));

                Assert.IsTrue(subject.StateChanged);

                using (var oswf = mosc1.CreateWriter())
                {
                    oswf.SaveState(subject);
                }

                Assert.IsTrue(subject.StateChanged);

                subject.OnStateSaved();

                Assert.IsFalse(subject.StateChanged);
            }

            {
                var subject = GetSubject(id, svc);

                Assert.IsTrue(subject.StateChanged);

                using (var osrf = mosc1.CreateReader())
                {
                    osrf.LoadState(subject);
                }

                Assert.IsFalse(subject.StateChanged);

                var xs = (ISubscribable <int>)subject;

                var d2 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d2).Initialize(CreateOperatorContext(new Uri("tests://qux/2"), svc, sch));

                var d3 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d3).Initialize(CreateOperatorContext(new Uri("tests://qux/3"), svc, sch));

                Assert.IsFalse(subject.StateChanged);

                var d4 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d4).Initialize(CreateOperatorContext(new Uri("tests://qux/4"), svc, sch));

                Assert.IsTrue(subject.StateChanged);

                var d5 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d5).Initialize(CreateOperatorContext(new Uri("tests://qux/5"), svc, sch));

                d3.Dispose();

                subject.Seal();

                Assert.IsTrue(subject.StateChanged);

                using (var oswf = mosc2.CreateWriter())
                {
                    oswf.SaveState(subject);
                }

                Assert.IsTrue(subject.StateChanged);

                subject.OnStateSaved();

                Assert.IsFalse(subject.StateChanged);
            }

            {
                var subject = GetSubject(id, svc);

                Assert.IsTrue(subject.StateChanged);

                using (var osrf = mosc2.CreateReader())
                {
                    osrf.LoadState(subject);
                }

                Assert.IsFalse(subject.StateChanged);

                var xs = (ISubscribable <int>)subject;

                var d2 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d2).Initialize(CreateOperatorContext(new Uri("tests://qux/2"), svc, sch));

                var d4 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d4).Initialize(CreateOperatorContext(new Uri("tests://qux/4"), svc, sch));

                var d5 = xs.Subscribe(Observer.Nop <int>());
                new SubscriptionInitializeVisitor(d5).Initialize(CreateOperatorContext(new Uri("tests://qux/5"), svc, sch));

                Assert.IsFalse(subject.StateChanged);

                // gets sealed after all subscriptions have been recreated
                Assert.ThrowsException <InvalidOperationException>(() => subject.Subscribe(Observer.Nop <int>()));
            }
        }