protected void DisconnectFromNode(RachisConsensus <CountingStateMachine> node) { foreach (var follower in RachisConsensuses.Where(x => x.Url != node.Url)) { Disconnect(follower.Url, node.Url); } }
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); } }
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); }
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); }
protected List <RachisConsensus <CountingStateMachine> > GetFollowers() { return(RachisConsensuses.Where( x => x.CurrentState != RachisState.Leader && x.CurrentState != RachisState.LeaderElect).ToList()); }