示例#1
0
 protected void DisconnectFromNode(RachisConsensus <CountingStateMachine> node)
 {
     foreach (var follower in RachisConsensuses.Where(x => x.Url != node.Url))
     {
         Disconnect(follower.Url, node.Url);
     }
 }
示例#2
0
        protected async Task <Task> ActionWithLeader(Func <RachisConsensus <CountingStateMachine>, Task> action)
        {
            var       retires = 5;
            Exception lastException;

            using (var cts = new CancellationTokenSource())
            {
                do
                {
                    try
                    {
                        var tasks = RachisConsensuses.Select(x => x.WaitForState(RachisState.Leader, cts.Token));
                        await Task.WhenAny(tasks);

                        var leader = RachisConsensuses.Single(x => x.CurrentState == RachisState.Leader);
                        return(action(leader));
                    }
                    catch (Exception e)
                    {
                        lastException = e;
                    }
                } while (retires-- > 0);
            }

            if (lastException != null)
            {
                throw lastException;
            }

            throw new InvalidOperationException("Should never happened!");
        }
 protected void ReconnectBiDirectionalFromNode(RachisConsensus <CountingStateMachine> node)
 {
     foreach (var follower in RachisConsensuses.Where(x => x.Url != node.Url))
     {
         Reconnect(follower.Url, node.Url);
         Reconnect(node.Url, follower.Url);
     }
 }
示例#4
0
        protected RachisConsensus <CountingStateMachine> SetupServer(bool bootstrap = false, int port = 0, int electionTimeout = 300, [CallerMemberName] string caller = null)
        {
            var tcpListener = new TcpListener(IPAddress.Loopback, port);

            tcpListener.Start();
            char ch;

            if (bootstrap)
            {
                ch = (char)65;
            }
            else
            {
                ch = (char)(65 + Interlocked.Increment(ref _count));
            }

            var url = $"tcp://localhost:{((IPEndPoint)tcpListener.LocalEndpoint).Port}/?{caller}#{ch}";

            var server = StorageEnvironmentOptions.CreateMemoryOnly();

            int seed          = PredictableSeeds ? _random.Next(int.MaxValue) : (int)Interlocked.Read(ref _count);
            var configuration = RavenConfiguration.CreateForServer(caller);

            configuration.Initialize();
            configuration.Core.RunInMemory        = true;
            configuration.Core.PublicServerUrl    = new UriSetting($"http://localhost:{((IPEndPoint)tcpListener.LocalEndpoint).Port}");
            configuration.Cluster.ElectionTimeout = new TimeSetting(electionTimeout, TimeUnit.Milliseconds);
            var serverStore = new RavenServer(configuration)
            {
                ThrowOnLicenseActivationFailure = true
            }.ServerStore;

            serverStore.Initialize();
            var rachis             = new RachisConsensus <CountingStateMachine>(serverStore, seed);
            var storageEnvironment = new StorageEnvironment(server);

            rachis.Initialize(storageEnvironment, configuration, configuration.Core.ServerUrls[0], out _);
            rachis.OnDispose += (sender, args) =>
            {
                serverStore.Dispose();
                storageEnvironment.Dispose();
            };
            if (bootstrap)
            {
                rachis.Bootstrap(url, "A");
            }

            rachis.Url = url;
            _listeners.Add(tcpListener);
            RachisConsensuses.Add(rachis);
            var task = AcceptConnection(tcpListener, rachis);

            return(rachis);
        }
示例#5
0
        protected RachisConsensus <CountingStateMachine> SetupServer(bool bootstrap = false, int port = 0, int electionTimeout = 300, [CallerMemberName] string caller = null)
        {
            var tcpListener = new TcpListener(IPAddress.Loopback, port);

            tcpListener.Start();
            var ch = (char)(66 + _count++);

            if (bootstrap)
            {
                ch = (char)65;
                _count--;
            }

            var url = "tcp://localhost:" + ((IPEndPoint)tcpListener.LocalEndpoint).Port + "/?" + caller + "#" + ch;

            var server = StorageEnvironmentOptions.CreateMemoryOnly();

            int seed          = PredictableSeeds ? _random.Next(int.MaxValue) : _count;
            var configuration = new RavenConfiguration(caller, ResourceType.Server);

            configuration.Initialize();
            configuration.Core.RunInMemory        = true;
            configuration.Core.PublicServerUrl    = new UriSetting($"http://localhost:{((IPEndPoint)tcpListener.LocalEndpoint).Port}");
            configuration.Cluster.ElectionTimeout = new TimeSetting(electionTimeout, TimeUnit.Milliseconds);
            var serverStore = new RavenServer(configuration).ServerStore;

            serverStore.Initialize();
            var rachis             = new RachisConsensus <CountingStateMachine>(serverStore, seed);
            var storageEnvironment = new StorageEnvironment(server);

            rachis.Initialize(storageEnvironment, configuration, configuration.Core.ServerUrls[0]);
            rachis.OnDispose += (sender, args) =>
            {
                serverStore.Dispose();
                storageEnvironment.Dispose();
            };
            if (bootstrap)
            {
                rachis.Bootstrap(url, "A");
            }

            rachis.Url = url;
            _listeners.Add(tcpListener);
            RachisConsensuses.Add(rachis);
            var task = AcceptConnection(tcpListener, rachis);

            return(rachis);
        }
示例#6
0
 protected List <RachisConsensus <CountingStateMachine> > GetFollowers()
 {
     return(RachisConsensuses.Where(
                x => x.CurrentState != RachisState.Leader &&
                x.CurrentState != RachisState.LeaderElect).ToList());
 }