Пример #1
0
        public void WaitForTopologyStabilization(string s, RavenServer workingServer, int rehabCount, int memberCount)
        {
            using (var tempStore = new DocumentStore
            {
                Database = s,
                Urls = new[] { workingServer.WebUrl },
                Conventions = new DocumentConventions
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                Topology topo;
                using (var context = JsonOperationContext.ShortTermSingleUse())
                {
                    var value = WaitForValue(() =>
                    {
                        var topologyGetCommand = new GetDatabaseTopologyCommand();
                        tempStore.GetRequestExecutor().Execute(topologyGetCommand, context);
                        topo        = topologyGetCommand.Result;
                        int rehab   = 0;
                        int members = 0;
                        topo.Nodes.ForEach(n =>
                        {
                            switch (n.ServerRole)
                            {
                            case ServerNode.Role.Rehab:
                                rehab++;
                                break;

                            case ServerNode.Role.Member:
                                members++;
                                break;
                            }
                        });
                        return(new Tuple <int, int>(rehab, members));
                    }, new Tuple <int, int>(rehabCount, memberCount));
                }
            }
        }
Пример #2
0
        public async Task Round_robin_load_balancing_with_failing_node_should_work()
        {
            var databaseName = GetDatabaseName();

            var(nodes, leader) = await CreateRaftCluster(3);

            var followers = Servers.Where(x => x.ServerStore.IsLeader() == false).ToArray();

            var conventionsForLoadBalancing = new DocumentConventions
            {
                ReadBalanceBehavior = ReadBalanceBehavior.RoundRobin
            };

            using (var leaderStore = new DocumentStore
            {
                Urls = new[] { leader.WebUrl },
                Database = databaseName,
                Conventions = conventionsForLoadBalancing
            })
                using (var follower1 = new DocumentStore
                {
                    Urls = new[] { followers[0].WebUrl },
                    Database = databaseName,
                    Conventions = conventionsForLoadBalancing
                })
                    using (var follower2 = new DocumentStore
                    {
                        Urls = new[] { followers[1].WebUrl },
                        Database = databaseName,
                        Conventions = conventionsForLoadBalancing
                    })
                        using (var context = JsonOperationContext.ShortTermSingleUse())
                        {
                            leaderStore.Initialize();
                            follower1.Initialize();
                            follower2.Initialize();

                            var(index, _) = await CreateDatabaseInCluster(databaseName, 3, leader.WebUrl);
                            await WaitForRaftIndexToBeAppliedInCluster(index, TimeSpan.FromSeconds(30));

                            var leaderRequestExecutor = leaderStore.GetRequestExecutor();

                            //wait until all nodes in database cluster are members (and not promotables)
                            //GetDatabaseTopologyCommand -> does not retrieve promotables
                            var topology = new Topology();
                            while (topology.Nodes?.Count != 3)
                            {
                                var topologyGetCommand = new GetDatabaseTopologyCommand();
                                await leaderRequestExecutor.ExecuteAsync(topologyGetCommand, context);

                                topology = topologyGetCommand.Result;
                                Thread.Sleep(50);
                            }

                            foreach (var server in Servers)
                            {
                                await server.ServerStore.Cluster.WaitForIndexNotification(index);
                            }

                            using (var session = leaderStore.OpenSession())
                            {
                                session.Store(new User {
                                    Name = "John Dow"
                                });
                                session.Store(new User {
                                    Name = "Jack Dow"
                                });
                                session.Store(new User {
                                    Name = "Jane Dow"
                                });
                                session.Store(new User {
                                    Name = "FooBar"
                                }, "marker");
                                session.SaveChanges();

                                await WaitForDocumentInClusterAsync <User>(nodes,
                                                                           databaseName,
                                                                           "marker",
                                                                           x => true,
                                                                           leader.ServerStore.Configuration.Cluster.OperationTimeout.AsTimeSpan);
                            }

                            using (var requestExecutor = RequestExecutor.Create(follower1.Urls, databaseName, null, follower1.Conventions))
                            {
                                do //make sure there are three nodes in the topology
                                {
                                    await Task.Delay(100);
                                } while (requestExecutor.TopologyNodes == null);

                                DisposeServerAndWaitForFinishOfDisposal(leader);

                                var failedRequests = new HashSet <(string, Exception)>();

#pragma warning disable CS0618 // Type or member is obsolete
                                requestExecutor.FailedRequest += (url, e) => failedRequests.Add((url, e));
#pragma warning restore CS0618 // Type or member is obsolete

                                using (var tmpContext = JsonOperationContext.ShortTermSingleUse())
                                {
                                    for (var sessionId = 0; sessionId < 5; sessionId++)
                                    {
                                        requestExecutor.Cache.Clear(); //make sure we do not use request cache
                                        await requestExecutor.ExecuteAsync(new GetStatisticsOperation().GetCommand(DocumentConventions.Default, tmpContext), tmpContext, new SessionInfo(sessionId, false));
                                    }
                                }
                            }
                        }
        }
Пример #3
0
        public async Task Fastst_node_should_choose_the_node_without_delay()
        {
            NoTimeouts();
            var databaseName = GetDatabaseName();

            var(leader, serversToProxies) = await CreateRaftClusterWithProxiesAsync(3);

            var followers = Servers.Where(x => x.ServerStore.IsLeader() == false).ToArray();

            var conventionsForLoadBalancing = new DocumentConventions
            {
                ReadBalanceBehavior = ReadBalanceBehavior.FastestNode
            };

            //set proxies with delays to all servers except follower2
            using (var leaderStore = new DocumentStore
            {
                Urls = new[] { ReplacePort(leader.WebUrl, serversToProxies[leader].Port) },
                Database = databaseName,
                Conventions = conventionsForLoadBalancing
            })
            {
                leaderStore.Initialize();

                var(index, _) = await CreateDatabaseInCluster(databaseName, 3, leader.WebUrl);
                await WaitForRaftIndexToBeAppliedInCluster(index, TimeSpan.FromSeconds(30));

                var leaderRequestExecutor = leaderStore.GetRequestExecutor();

                //make sure we have updated topology --> more deterministic test
                await leaderRequestExecutor.UpdateTopologyAsync(new RequestExecutor.UpdateTopologyParameters(new ServerNode
                {
                    ClusterTag = leader.ServerStore.NodeTag,
                    Database   = databaseName,
                    Url        = leader.WebUrl
                })
                {
                    TimeoutInMs = 5000
                });

                ApplyProxiesOnRequestExecutor(serversToProxies, leaderRequestExecutor);

                //wait until all nodes in database cluster are members (and not promotables)
                //GetDatabaseTopologyCommand -> does not retrieve promotables
                using (var context = JsonOperationContext.ShortTermSingleUse())
                {
                    var topology = new Topology();
                    while (topology.Nodes?.Count != 3)
                    {
                        var topologyGetCommand = new GetDatabaseTopologyCommand();
                        await leaderRequestExecutor.ExecuteAsync(topologyGetCommand, context).ConfigureAwait(false);

                        topology = topologyGetCommand.Result;
                        Thread.Sleep(50);
                    }
                }

                //set delays to all servers except follower2
                foreach (var server in Servers)
                {
                    if (server == followers[1])
                    {
                        continue;
                    }

                    serversToProxies[server].ConnectionDelay = 300;
                }

                using (var session = leaderStore.OpenSession())
                {
                    session.Store(new User {
                        Name = "John Dow"
                    }, "users/1");
                    session.SaveChanges();
                }

                while (leaderRequestExecutor.InSpeedTestPhase)
                {
                    using (var session = leaderStore.OpenSession())
                    {
                        session.Load <User>("users/1");
                    }
                }

                var fastest        = leaderRequestExecutor.GetFastestNode().Result.Node;
                var follower2Proxy = ReplacePort(followers[1].WebUrl, serversToProxies[followers[1]].Port);

                Assert.Equal(follower2Proxy, fastest.Url);
            }
        }
Пример #4
0
        public async Task Round_robin_load_balancing_should_work()
        {
            var databaseName = GetDatabaseName();

            var(nodes, leader) = await CreateRaftCluster(3);

            var followers = Servers.Where(x => x.ServerStore.IsLeader() == false).ToArray();
            var conventionsForLoadBalancing = new DocumentConventions
            {
                ReadBalanceBehavior = ReadBalanceBehavior.RoundRobin
            };

            using (var leaderStore = new DocumentStore
            {
                Urls = new[] { leader.WebUrl },
                Database = databaseName,
                Conventions = conventionsForLoadBalancing
            })
                using (var follower1 = new DocumentStore
                {
                    Urls = new[] { followers[0].WebUrl },
                    Database = databaseName,
                    Conventions = conventionsForLoadBalancing
                })
                    using (var follower2 = new DocumentStore
                    {
                        Urls = new[] { followers[1].WebUrl },
                        Database = databaseName,
                        Conventions = conventionsForLoadBalancing
                    })
                        using (var context = JsonOperationContext.ShortTermSingleUse())
                        {
                            leaderStore.Initialize();
                            follower1.Initialize();
                            follower2.Initialize();

                            var(index, _) = await CreateDatabaseInCluster(databaseName, 3, leader.WebUrl);
                            await WaitForRaftIndexToBeAppliedInCluster(index, TimeSpan.FromSeconds(30));

                            var leaderRequestExecutor = leaderStore.GetRequestExecutor();

                            //make sure we have updated topology --> more deterministic test
                            await leaderRequestExecutor.UpdateTopologyAsync(new RequestExecutor.UpdateTopologyParameters(new ServerNode
                            {
                                ClusterTag = leader.ServerStore.NodeTag,
                                Database   = databaseName,
                                Url        = leader.WebUrl
                            })
                            {
                                TimeoutInMs = 5000,
                                ForceUpdate = true
                            });

                            //wait until all nodes in database cluster are members (and not promotables)
                            //GetDatabaseTopologyCommand -> does not retrieve promotables
                            var topology = new Topology();
                            while (topology.Nodes?.Count != 3)
                            {
                                var topologyGetCommand = new GetDatabaseTopologyCommand();
                                await leaderRequestExecutor.ExecuteAsync(topologyGetCommand, context);

                                topology = topologyGetCommand.Result;
                                Thread.Sleep(50);
                            }

                            foreach (var server in Servers)
                            {
                                await server.ServerStore.Cluster.WaitForIndexNotification(index);
                            }

                            using (var session = leaderStore.OpenSession())
                            {
                                session.Store(new User {
                                    Name = "John Dow"
                                });
                                session.Store(new User {
                                    Name = "Jack Dow"
                                });
                                session.Store(new User {
                                    Name = "Jane Dow"
                                });
                                session.Store(new User {
                                    Name = "FooBar"
                                }, "marker");
                                session.SaveChanges();

                                await WaitForDocumentInClusterAsync <User>(nodes, databaseName, "marker", x => true, leader.ServerStore.Configuration.Cluster.OperationTimeout.AsTimeSpan);
                            }

                            var usedUrls = new List <string>();

                            for (var i = 0; i < 3; i++)
                            {
                                using (var session = leaderStore.OpenSession())
                                {
                                    // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                                    session.Query <User>().Where(u => u.Name.StartsWith("Ja")).ToList();
                                    usedUrls.Add((await session.Advanced.GetCurrentSessionNode()).Url.ToLower());
                                }
                            }

                            foreach (var url in usedUrls)
                            {
                                Assert.Single(usedUrls, url);
                            }
                        }
        }