Пример #1
0
        public void CleanUpDeletable()
        {
            var transport = new MockTransport(A, new string[0]);

            using (var backend = new GossipBackend(transport, new GossipConfiguration
            {
                CleanUpInterval = 100,
                RemovableItemLingerMs = 200,
            }))
            {
                // must first set a non-deletable one, cause Set rejects deletable writes if it has no
                // existing value for that key.
                backend.Set("test", new DummyDeletable {
                    CanDelete = false
                }.Version(1));
                Assert.AreEqual(VectorRelationship.Greater,
                                backend.Set("test", new DummyDeletable {
                    CanDelete = true
                }.Version(2)));

                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <DummyDeletable> >("test"));
                Thread.Sleep(100);
                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <DummyDeletable> >("test"));
                Thread.Sleep(250);
                Assert.IsNull(backend.TryGetWithInfo <IntVersioned <DummyDeletable> >("test"));
            }
        }
Пример #2
0
        public void CleanUpRevived()
        {
            var transport = new MockTransport(A, new string[0]);

            using (var backend = new GossipBackend(transport, new GossipConfiguration
            {
                CleanUpInterval = 100,
                RemovableItemLingerMs = 200,
            }))
            {
                backend.Set("test", "something".Version(1), 100);

                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
                Thread.Sleep(250);
                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
                // we will revive it now
                Assert.AreEqual(VectorRelationship.Equal,
                                backend.Set("test", "something".Version(1), 100));

                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
                Thread.Sleep(250);
                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
                Thread.Sleep(250);
                Assert.IsNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
            }
        }
Пример #3
0
        public void KeyMissing_Basics()
        {
            var currValue = "stored value".Version(7);
            var transport = new MockTransport(A, new string[0]);

            using (var backend = new GossipBackend(transport, new GossipConfiguration
            {
                CleanUpInterval = 100,
                RemovableItemLingerMs = 100,
            }))
            {
                void Provider(object sender, KeyMissingEventArgs args) => args.UseValue(currValue, expiresInMs: 100);

                Shield.InTransaction(() =>
                {
                    backend.KeyMissing.Subscribe(Provider);
                    backend.Changed.Subscribe((_, args) => Shield.SideEffect(() =>
                                                                             currValue = (IntVersioned <string>)args.NewValue));
                });

                var resWithInfo = backend.TryGetWithInfo <IntVersioned <string> >("key");

                Assert.AreEqual("stored value", resWithInfo.Value.Value);
                Assert.AreEqual(7, resWithInfo.Value.Version);
                Assert.AreEqual(100, resWithInfo.ExpiresInMs);

                // enough time for a full clean-up of the key. since the provider is still subscribed, the
                // clean-up might accidentally refetch the key. this will test whether it does.
                Thread.Sleep(400);

                // confirm clean-up
                Shield.InTransaction(() => backend.KeyMissing.Unsubscribe(Provider));
                Assert.IsNull(backend.TryGetWithInfo <IntVersioned <string> >("key"));
                Shield.InTransaction(() => backend.KeyMissing.Subscribe(Provider));

                Assert.AreEqual(VectorRelationship.Less, backend.Set("key", "failed write".Version(2), 100));

                Thread.Sleep(50);

                resWithInfo = backend.TryGetWithInfo <IntVersioned <string> >("key");

                Assert.AreEqual("stored value", resWithInfo.Value.Value);
                Assert.AreEqual(7, resWithInfo.Value.Version);
                // it seems the Thread.Sleep above lasts slightly less than 50 ms? cause ExpiresInMs is sometimes still > 50...
                Assert.IsTrue(resWithInfo.ExpiresInMs <= 60);

                Assert.AreEqual(VectorRelationship.Greater, backend.Set("key", "successful write".Version(8), 100));

                Thread.Sleep(150);

                resWithInfo = backend.TryGetWithInfo <IntVersioned <string> >("key");

                Assert.AreEqual("successful write", resWithInfo.Value.Value);
                Assert.AreEqual(8, resWithInfo.Value.Version);
                Assert.AreEqual(100, resWithInfo.ExpiresInMs);
            }
        }
        public void Init()
        {
            var transport = new TcpTransport("Node", new Dictionary <string, IPEndPoint> {
                { "Node", new IPEndPoint(IPAddress.Loopback, 2001) }
            });

            transport.StartListening();
            _backend = new GossipBackend(transport, new GossipConfiguration {
                CleanUpInterval = 100, RemovableItemLingerMs = 200
            });
        }
Пример #5
0
        public void KeyMissing_Tombstone()
        {
            var currValue = "deleted value".Version(7);
            var isDeleted = true;
            var transport = new MockTransport(A, new string[0]);

            using (var backend = new GossipBackend(transport, new GossipConfiguration
            {
                CleanUpInterval = 100,
                RemovableItemLingerMs = 100,
            }))
            {
                void Provider(object sender, KeyMissingEventArgs args) => args.UseValue(currValue, isDeleted);

                Shield.InTransaction(() =>
                {
                    backend.KeyMissing.Subscribe(Provider);
                    backend.Changed.Subscribe((_, args) => Shield.SideEffect(() =>
                    {
                        currValue = (IntVersioned <string>)args.NewValue;
                        isDeleted = args.Deleted;
                    }));
                });

                Assert.AreEqual(VectorRelationship.Less, backend.Set("key", "failed write".Version(5)));

                var resWithInfo = backend.TryGetWithInfo <IntVersioned <string> >("key");

                Assert.AreEqual("deleted value", resWithInfo.Value.Value);
                Assert.AreEqual(7, resWithInfo.Value.Version);
                Assert.IsTrue(resWithInfo.Deleted);

                // enough time for a full clean-up of the key
                Thread.Sleep(400);

                // confirm clean-up
                Shield.InTransaction(() => backend.KeyMissing.Unsubscribe(Provider));
                Assert.IsNull(backend.TryGetWithInfo <IntVersioned <string> >("key"));
                Shield.InTransaction(() => backend.KeyMissing.Subscribe(Provider));

                // this will still fail, because of the KeyMissing event restoring the tombstone.
                Assert.AreEqual(VectorRelationship.Less, backend.Set("key", "failed write".Version(5)));

                // but this will work
                Assert.AreEqual(VectorRelationship.Greater, backend.Set("key", "successful write".Version(8)));

                resWithInfo = backend.TryGetWithInfo <IntVersioned <string> >("key");

                Assert.AreEqual("successful write", resWithInfo.Value.Value);
                Assert.AreEqual(8, resWithInfo.Value.Version);
            }
        }
Пример #6
0
        public void CleanUpExpired()
        {
            var transport = new MockTransport(A, new string[0]);

            using (var backend = new GossipBackend(transport, new GossipConfiguration
            {
                CleanUpInterval = 100,
                RemovableItemLingerMs = 200,
            }))
            {
                backend.Set("test", "something".Version(1), 100);

                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
                Thread.Sleep(250);
                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
                Thread.Sleep(200);
                Assert.IsNull(backend.TryGetWithInfo <IntVersioned <string> >("test"));
            }
        }
Пример #7
0
        public void CleanUpNonDeletable()
        {
            // should not be cleaned up, of course.
            var transport = new MockTransport(A, new string[0]);

            using (var backend = new GossipBackend(transport, new GossipConfiguration
            {
                CleanUpInterval = 100,
                RemovableItemLingerMs = 200,
            }))
            {
                backend.Set("test", new DummyDeletable {
                    CanDelete = false
                }.Version(1));

                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <DummyDeletable> >("test"));
                Thread.Sleep(350);
                Assert.IsNotNull(backend.TryGetWithInfo <IntVersioned <DummyDeletable> >("test"));
            }
        }
 public void Cleanup()
 {
     _backend.Dispose();
     _backend = null;
 }