Ejemplo n.º 1
0
        public void DisposingOneSubscriptionShouldNotAffectOnNotificationsOfOthers()
        {
            SubscriptionWorker <User> subscription1 = null;
            SubscriptionWorker <User> subscription2 = null;
            var store = GetDocumentStore();

            try
            {
                var id1 = store.Subscriptions.Create(new SubscriptionCreationOptions <User>());
                var id2 = store.Subscriptions.Create(new SubscriptionCreationOptions <User>());

                using (var s = store.OpenSession())
                {
                    s.Store(new User(), "users/1");
                    s.Store(new User(), "users/2");
                    s.SaveChanges();
                }

                subscription1 = store.Subscriptions.GetSubscriptionWorker <User>(id1);
                var items1 = new BlockingCollection <User>();
                subscription1.Run(x => x.Items.ForEach(i => items1.Add(i.Result)));

                subscription2 = store.Subscriptions.GetSubscriptionWorker <User>(id2);
                var items2 = new BlockingCollection <User>();
                subscription2.Run(x => x.Items.ForEach(i => items2.Add(i.Result)));


                Assert.True(items1.TryTake(out var user, _reasonableWaitTime));
                Assert.Equal("users/1", user.Id);
                Assert.True(items1.TryTake(out user, _reasonableWaitTime));
                Assert.Equal("users/2", user.Id);

                Assert.True(items2.TryTake(out user, _reasonableWaitTime));
                Assert.Equal("users/1", user.Id);
                Assert.True(items2.TryTake(out user, _reasonableWaitTime));
                Assert.Equal("users/2", user.Id);

                subscription1.Dispose();

                using (var s = store.OpenSession())
                {
                    s.Store(new User(), "users/3");
                    s.Store(new User(), "users/4");
                    s.SaveChanges();
                }

                Assert.True(items2.TryTake(out user, _reasonableWaitTime));
                Assert.Equal("users/3", user.Id);
                Assert.True(items2.TryTake(out user, _reasonableWaitTime));
                Assert.Equal("users/4", user.Id);
            }
            finally
            {
                subscription1.Dispose();
                subscription2.Dispose();
                store.Dispose();
            }
        }
Ejemplo n.º 2
0
        public async Task CanReleaseSubscription()
        {
            SubscriptionWorker <dynamic> subscriptionWorker            = null;
            SubscriptionWorker <dynamic> throwingSubscriptionWorker    = null;
            SubscriptionWorker <dynamic> notThrowingSubscriptionWorker = null;

            var store = GetDocumentStore();

            try
            {
                Server.ServerStore.Observer.Suspended = true;
                var id = store.Subscriptions.Create(new SubscriptionCreationOptions <User>());
                subscriptionWorker = store.Subscriptions.GetSubscriptionWorker(new SubscriptionWorkerOptions(id)
                {
                    Strategy = SubscriptionOpeningStrategy.OpenIfFree
                });
                var mre = new AsyncManualResetEvent();
                PutUserDoc(store);
                var t = subscriptionWorker.Run(x =>
                {
                    mre.Set();
                });
                Assert.True(await mre.WaitAsync(_reasonableWaitTime));
                mre.Reset();

                throwingSubscriptionWorker = store.Subscriptions.GetSubscriptionWorker(new SubscriptionWorkerOptions(id)
                {
                    Strategy = SubscriptionOpeningStrategy.OpenIfFree
                });
                var subscriptionTask = throwingSubscriptionWorker.Run(x => { });

                Assert.True(await Assert.ThrowsAsync <SubscriptionInUseException>(() =>
                {
                    return(subscriptionTask);
                }).WaitAsync(_reasonableWaitTime));

                store.Subscriptions.DropConnection(id);

                notThrowingSubscriptionWorker = store.Subscriptions.GetSubscriptionWorker(new SubscriptionWorkerOptions(id));

                t = notThrowingSubscriptionWorker.Run(x =>
                {
                    mre.Set();
                });

                PutUserDoc(store);

                Assert.True(await mre.WaitAsync(_reasonableWaitTime));
            }
            finally
            {
                subscriptionWorker?.Dispose();
                throwingSubscriptionWorker?.Dispose();
                notThrowingSubscriptionWorker?.Dispose();
                store.Dispose();
            }
        }
Ejemplo n.º 3
0
        public async Task DistributedRevisionsSubscription(int nodesAmount)
        {
            var uniqueRevisions = new HashSet <string>();
            var uniqueDocs      = new HashSet <string>();

            var(_, leader) = await CreateRaftCluster(nodesAmount).ConfigureAwait(false);

            var defaultDatabase = GetDatabaseName();

            await CreateDatabaseInCluster(defaultDatabase, nodesAmount, leader.WebUrl).ConfigureAwait(false);

            using (var store = new DocumentStore
            {
                Urls = new[] { leader.WebUrl },
                Database = defaultDatabase
            }.Initialize())
            {
                await SetupRevisions(leader, defaultDatabase).ConfigureAwait(false);

                var reachedMaxDocCountMre = new AsyncManualResetEvent();
                var ackSent = new AsyncManualResetEvent();

                var continueMre = new AsyncManualResetEvent();

                await GenerateDistributedRevisionsDataAsync(defaultDatabase);

                var subscriptionId = await store.Subscriptions.CreateAsync <Revision <User> >().ConfigureAwait(false);

                var docsCount              = 0;
                var revisionsCount         = 0;
                var expectedRevisionsCount = 0;
                SubscriptionWorker <Revision <User> > subscription = null;
                int i;
                for (i = 0; i < 10; i++)
                {
                    subscription = store.Subscriptions.GetSubscriptionWorker <Revision <User> >(new SubscriptionWorkerOptions(subscriptionId)
                    {
                        MaxErroneousPeriod = nodesAmount == 5 ? TimeSpan.FromSeconds(15) : TimeSpan.FromSeconds(5),
                        MaxDocsPerBatch    = 1,
                        TimeToWaitBeforeConnectionRetry = TimeSpan.FromMilliseconds(100)
                    });

                    subscription.AfterAcknowledgment += async b =>
                    {
                        Assert.True(await continueMre.WaitAsync(TimeSpan.FromSeconds(60)));

                        try
                        {
                            if (revisionsCount == expectedRevisionsCount)
                            {
                                continueMre.Reset();
                                ackSent.Set();
                            }

                            Assert.True(await continueMre.WaitAsync(TimeSpan.FromSeconds(60)));
                        }
                        catch (Exception)
                        {
                        }
                    };
                    var started = new AsyncManualResetEvent();

                    var task = subscription.Run(b =>
                    {
                        started.Set();
                        HandleSubscriptionBatch(nodesAmount, b, uniqueDocs, ref docsCount, uniqueRevisions, reachedMaxDocCountMre, ref revisionsCount);
                    });
                    var cont = task.ContinueWith(t =>
                    {
                        reachedMaxDocCountMre.SetException(t.Exception);
                        ackSent.SetException(t.Exception);
                    }, TaskContinuationOptions.OnlyOnFaulted);

                    await Task.WhenAny(task, started.WaitAsync(TimeSpan.FromSeconds(60)));

                    if (started.IsSet)
                    {
                        break;
                    }

                    Assert.IsType <SubscriptionDoesNotExistException>(task.Exception.InnerException);

                    subscription.Dispose();
                }

                Assert.NotEqual(i, 10);

                expectedRevisionsCount = nodesAmount + 2;
                continueMre.Set();

                Assert.True(await ackSent.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (1st assert)");
                ackSent.Reset(true);

                var disposedTag = await KillServerWhereSubscriptionWorks(defaultDatabase, subscription.SubscriptionName).ConfigureAwait(false);
                await WaitForResponsibleNodeToChange(defaultDatabase, subscription.SubscriptionName, disposedTag);

                continueMre.Set();
                expectedRevisionsCount += 2;

                Assert.True(await ackSent.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (2nd assert)");
                ackSent.Reset(true);
                continueMre.Set();

                expectedRevisionsCount = (int)Math.Pow(nodesAmount, 2);
                if (nodesAmount == 5)
                {
                    var secondDisposedTag = await KillServerWhereSubscriptionWorks(defaultDatabase, subscription.SubscriptionName).ConfigureAwait(false);
                    await WaitForResponsibleNodeToChange(defaultDatabase, subscription.SubscriptionName, secondDisposedTag);
                }

                Assert.True(await reachedMaxDocCountMre.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (3rd assert)");
            }
        }
Ejemplo n.º 4
0
        public async Task ShouldKeepPullingDocsAfterServerRestart()
        {
            var dataPath = NewDataPath();

            IDocumentStore store  = null;
            RavenServer    server = null;
            SubscriptionWorker <dynamic> subscriptionWorker = null;

            try
            {
                var co = new ServerCreationOptions
                {
                    RunInMemory    = false,
                    CustomSettings = new Dictionary <string, string>()
                    {
                        [RavenConfiguration.GetKey(x => x.Core.DataDirectory)] = dataPath
                    },
                    RegisterForDisposal = false
                };

                server = GetNewServer(co);

                store = new DocumentStore()
                {
                    Urls     = new[] { server.ServerStore.GetNodeHttpServerUrl() },
                    Database = "RavenDB_2627",
                }.Initialize();

                var doc    = new DatabaseRecord(store.Database);
                var result = store.Maintenance.Server.Send(new CreateDatabaseOperationWithoutNameValidation(doc));
                await WaitForRaftIndexToBeAppliedInCluster(result.RaftCommandIndex, _reasonableWaitTime);

                using (var session = store.OpenSession())
                {
                    session.Store(new User());
                    session.Store(new User());
                    session.Store(new User());
                    session.Store(new User());

                    session.SaveChanges();
                }

                var id = store.Subscriptions.Create(new SubscriptionCreationOptions <User>());

                subscriptionWorker = store.Subscriptions.GetSubscriptionWorker(new SubscriptionWorkerOptions(id)
                {
                    TimeToWaitBeforeConnectionRetry = TimeSpan.FromSeconds(1),
                    MaxDocsPerBatch = 1
                });


                var gotBatch = new ManualResetEventSlim();
                var gotArek  = new ManualResetEventSlim();
                var t        = subscriptionWorker.Run(x =>
                {
                    gotBatch.Set();

                    foreach (var item in x.Items)
                    {
                        if (item.Id == "users/arek")
                        {
                            gotArek.Set();
                        }
                    }
                });

                Assert.True(gotBatch.Wait(_reasonableWaitTime));

                Server.ServerStore.DatabasesLandlord.UnloadDirectly(store.Database);

                for (int i = 0; i < 150; i++)
                {
                    try
                    {
                        using (var session = store.OpenSession())
                        {
                            session.Store(new User(), "users/arek");
                            session.SaveChanges();
                        }
                        break;
                    }
                    catch
                    {
                        Thread.Sleep(25);
                        if (i > 100)
                        {
                            throw;
                        }
                    }
                }

                Assert.True(gotArek.Wait(_reasonableWaitTime));
            }
            finally
            {
                subscriptionWorker?.Dispose();
                store?.Dispose();
                server.Dispose();
            }
        }
Ejemplo n.º 5
0
        public async Task MixedCluster_DistributedRevisionsSubscription()
        {
            var uniqueRevisions = new HashSet <string>();
            var uniqueDocs      = new HashSet <string>();
            var nodesAmount     = 5;

            var(leader, peers, local) = await CreateMixedCluster(new[]
            {
                "4.0.7-nightly-20180820-0400",
                "4.0.7-nightly-20180820-0400"
            }, 2, new Dictionary <string, string>
            {
                [RavenConfiguration.GetKey(x => x.Cluster.MoveToRehabGraceTime)] = "1"
            });

            var stores = await GetStores(leader, peers, local, modifyDocumentStore : s => s.Conventions.DisableTopologyUpdates = false);

            using (stores.Disposable)
            {
                var storeA = stores.Stores[0];
                var dbName = await CreateDatabase(storeA, nodesAmount);

                await Task.Delay(500);

                await RevisionsHelper.SetupRevisions(leader.ServerStore, dbName).ConfigureAwait(false);

                var reachedMaxDocCountMre = new AsyncManualResetEvent();
                var ackSent = new AsyncManualResetEvent();

                var continueMre = new AsyncManualResetEvent();
                GenerateDistributedRevisionsData(dbName, stores.Stores);

                var subscriptionId = await storeA.Subscriptions.CreateAsync <Revision <User> >(database : dbName).ConfigureAwait(false);

                var docsCount              = 0;
                var revisionsCount         = 0;
                var expectedRevisionsCount = 0;
                SubscriptionWorker <Revision <User> > subscription = null;
                int i;
                for (i = 0; i < 10; i++)
                {
                    subscription = storeA.Subscriptions.GetSubscriptionWorker <Revision <User> >(new SubscriptionWorkerOptions(subscriptionId)
                    {
                        MaxDocsPerBatch = 1,
                        TimeToWaitBeforeConnectionRetry = TimeSpan.FromMilliseconds(100)
                    }, dbName);

                    subscription.AfterAcknowledgment += async b =>
                    {
                        await continueMre.WaitAsync();

                        try
                        {
                            if (revisionsCount == expectedRevisionsCount)
                            {
                                continueMre.Reset();
                                ackSent.Set();
                            }

                            await continueMre.WaitAsync();
                        }
                        catch (Exception)
                        {
                        }
                    };
                    var started = new AsyncManualResetEvent();

                    var task = subscription.Run(b =>
                    {
                        started.Set();
                        HandleSubscriptionBatch(nodesAmount, b, uniqueDocs, ref docsCount, uniqueRevisions, reachedMaxDocCountMre, ref revisionsCount);
                    });

                    await Task.WhenAny(task, started.WaitAsync());

                    if (started.IsSet)
                    {
                        break;
                    }

                    Assert.IsType <SubscriptionDoesNotExistException>(task.Exception.InnerException);

                    subscription.Dispose();
                }

                Assert.NotEqual(i, 10);

                expectedRevisionsCount = nodesAmount + 2;
                continueMre.Set();

                Assert.True(await ackSent.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (1st assert)");
                ackSent.Reset(true);

                await KillServerWhereSubscriptionWorks(storeA, dbName, subscription.SubscriptionName, (leader, peers, local)).ConfigureAwait(false);

                continueMre.Set();
                expectedRevisionsCount += 2;

                Assert.True(await ackSent.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (2nd assert)");
                ackSent.Reset(true);
                continueMre.Set();
                expectedRevisionsCount = (int)Math.Pow(nodesAmount, 2);

                await KillServerWhereSubscriptionWorks(storeA, dbName, subscription.SubscriptionName, (leader, peers, local)).ConfigureAwait(false);

                Assert.True(await reachedMaxDocCountMre.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (3rd assert)");
            }
        }
Ejemplo n.º 6
0
 public void Dispose()
 {
     _subscription?.Dispose();
 }