Esempio n. 1
0
        public async Task CanSnapshotSubscriptionState()
        {
            var(_, leader) = await CreateRaftCluster(1, watcherCluster : true);

            using (var store = GetDocumentStore(options: new Options
            {
                Server = leader
            }))
            {
                var sub = await store.Subscriptions.CreateAsync <User>();

                var worker = store.Subscriptions.GetSubscriptionWorker <User>(sub);

                var waitForBatch = new ManualResetEvent(false);
                var t            = worker.Run((batch) => { waitForBatch.WaitOne(TimeSpan.FromSeconds(15)); });

                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new User());

                    await session.SaveChangesAsync();
                }

                var database = await leader.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database);

                database.SubscriptionStorage.GetSubscriptionFromServerStore(sub);


                var server2    = GetNewServer();
                var server2Url = server2.ServerStore.GetNodeHttpServerUrl();
                Servers.Add(server2);

                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(leader.WebUrl, null))
                    using (requestExecutor.ContextPool.AllocateOperationContext(out var ctx))
                    {
                        await requestExecutor.ExecuteAsync(new AddClusterNodeCommand(server2Url, watcher : true), ctx);

                        var addDatabaseNode = new AddDatabaseNodeOperation(store.Database);
                        await store.Maintenance.Server.SendAsync(addDatabaseNode);
                        await WaitAndAssertForValueAsync(() => GetMembersCount(store), 2);
                    }

                database = await server2.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database);

                var state = database.SubscriptionStorage.GetSubscriptionFromServerStore(sub);

                using (server2.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                    using (context.OpenReadTransaction())
                    {
                        Assert.Single(SubscriptionStorage.GetResendItems(context, store.Database, state.SubscriptionId));
                    }

                waitForBatch.Set();
            }
        }
Esempio n. 2
0
        public async Task CanSnapshotCompareExchangeTombstones()
        {
            var leader = await CreateRaftClusterAndGetLeader(1);


            using (var store = GetDocumentStore(options: new Options
            {
                Server = leader
            }))
            {
                using (var session = store.OpenAsyncSession(new SessionOptions
                {
                    TransactionMode = TransactionMode.ClusterWide
                }))
                {
                    session.Advanced.ClusterTransaction.CreateCompareExchangeValue("foo", "bar");
                    await session.SaveChangesAsync();

                    var result = await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync <string>("foo");

                    session.Advanced.ClusterTransaction.DeleteCompareExchangeValue(result);
                    await session.SaveChangesAsync();
                }

                var server2    = GetNewServer();
                var server2Url = server2.ServerStore.GetNodeHttpServerUrl();
                Servers.Add(server2);

                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(leader.WebUrl, null))
                    using (requestExecutor.ContextPool.AllocateOperationContext(out var ctx))
                    {
                        await requestExecutor.ExecuteAsync(new AddClusterNodeCommand(server2Url, watcher : true), ctx);

                        var addDatabaseNode = new AddDatabaseNodeOperation(store.Database);
                        await store.Maintenance.Server.SendAsync(addDatabaseNode);
                    }

                using (server2.ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx))
                    using (ctx.OpenReadTransaction())
                    {
                        Assert.True(server2.ServerStore.Cluster.HasCompareExchangeTombstones(ctx, store.Database));
                    }
            }
        }
        public async Task CanSnapshotCompareExchangeWithExpiration()
        {
            var count = 45;

            var(_, leader) = await CreateRaftCluster(1, watcherCluster : true);

            using (var store = GetDocumentStore(options: new Options
            {
                Server = leader
            }))
            {
                var expiry           = DateTime.Now.AddMinutes(2);
                var compareExchanges = new Dictionary <string, User>();
                await CompareExchangeExpirationTest.AddCompareExchangesWithExpire(count, compareExchanges, store, expiry);

                await CompareExchangeExpirationTest.AssertCompareExchanges(compareExchanges, store, expiry);

                using (leader.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                    using (context.OpenReadTransaction())
                    {
                        Assert.Equal(count, CompareExchangeExpirationStorage.GetExpiredValues(context, long.MaxValue).Count());
                    }

                var server2    = GetNewServer();
                var server2Url = server2.ServerStore.GetNodeHttpServerUrl();
                Servers.Add(server2);

                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(leader.WebUrl, null))
                    using (requestExecutor.ContextPool.AllocateOperationContext(out var ctx))
                    {
                        await requestExecutor.ExecuteAsync(new AddClusterNodeCommand(server2Url, watcher : true), ctx);

                        var addDatabaseNode = new AddDatabaseNodeOperation(store.Database);
                        await store.Maintenance.Server.SendAsync(addDatabaseNode);
                    }

                using (server2.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                    using (context.OpenReadTransaction())
                    {
                        Assert.Equal(count, CompareExchangeExpirationStorage.GetExpiredValues(context, long.MaxValue).Count());
                    }

                var now = DateTime.UtcNow;
                leader.ServerStore.Observer.Time.UtcDateTime = () => now.AddMinutes(3);

                var leaderCount = WaitForValue(() =>
                {
                    using (leader.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                        using (context.OpenReadTransaction())
                        {
                            return(CompareExchangeExpirationStorage.GetExpiredValues(context, long.MaxValue).Count());
                        }
                }, 0, interval: 333);

                Assert.Equal(0, leaderCount);

                var server2count = WaitForValue(() =>
                {
                    using (server2.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                        using (context.OpenReadTransaction())
                        {
                            return(CompareExchangeExpirationStorage.GetExpiredValues(context, long.MaxValue).Count());
                        }
                }, 0, interval: 333);

                Assert.Equal(0, server2count);
            }
        }
        public async Task CanSnapshotManyCompareExchangeWithExpiration()
        {
            DebuggerAttachedTimeout.DisableLongTimespan = true;
            var count = 1024;

            using var leader   = GetNewServer();
            using var follower = GetNewServer();
            using (var store = GetDocumentStore(new Options
            {
                Server = leader
            }))
            {
                var expiry           = DateTime.Now.AddMinutes(2);
                var compareExchanges = new Dictionary <string, User>();
                await AddCompareExchangesWithExpire(count, compareExchanges, store, expiry);
                await AssertCompareExchanges(compareExchanges, store, expiry);

                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(leader.WebUrl, null))
                    using (requestExecutor.ContextPool.AllocateOperationContext(out var ctx))
                    {
                        await requestExecutor.ExecuteAsync(new AddClusterNodeCommand(follower.WebUrl, watcher : true), ctx);

                        var cmd = new AddDatabaseNodeOperation(store.Database).GetCommand(store.Conventions, ctx);
                        await requestExecutor.ExecuteAsync(cmd, ctx);

                        await follower.ServerStore.Cluster.WaitForIndexNotification(cmd.Result.RaftCommandIndex);
                    }


                using (var fStore = GetDocumentStore(new Options
                {
                    Server = follower,
                    CreateDatabase = false,
                    ModifyDatabaseName = _ => store.Database,
                    ModifyDocumentStore = s => s.Conventions = new DocumentConventions {
                        DisableTopologyUpdates = true
                    }
                }))
                {
                    await AssertCompareExchanges(compareExchanges, store, expiry);

                    leader.ServerStore.Observer.Time.UtcDateTime = () => DateTime.UtcNow.AddMinutes(3);

                    var val = await WaitForValueAsync(async() =>
                    {
                        var stats = await store.Maintenance.SendAsync(new GetDetailedStatisticsOperation());
                        return(stats.CountOfCompareExchange);
                    }, 0);

                    Assert.Equal(0, val);

                    val = await WaitForValueAsync(async() =>
                    {
                        var stats = await fStore.Maintenance.SendAsync(new GetDetailedStatisticsOperation());
                        return(stats.CountOfCompareExchange);
                    }, 0);

                    Assert.Equal(0, val);
                }
            }
        }