public RaftEngine(RaftEngineOptions raftEngineOptions) { _raftEngineOptions = raftEngineOptions; EngineStatistics = new RaftEngineStatistics(this); Debug.Assert(raftEngineOptions.Stopwatch != null); _log = LogManager.GetLogger(raftEngineOptions.Name + "." + GetType().FullName); _eventLoopCancellationTokenSource = new CancellationTokenSource(); Name = raftEngineOptions.Name; PersistentState = new PersistentState(raftEngineOptions.Name, raftEngineOptions.StorageOptions, _eventLoopCancellationTokenSource.Token) { CommandSerializer = new JsonCommandSerializer() }; _currentTopology = PersistentState.GetCurrentTopology(); //warm up to make sure that the serializer don't take too long and force election timeout PersistentState.CommandSerializer.Serialize(new NopCommand()); var thereAreOthersInTheCluster = CurrentTopology.QuorumSize > 1; if (thereAreOthersInTheCluster == false && CurrentTopology.IsVoter(Name)) { PersistentState.UpdateTermTo(this, PersistentState.CurrentTerm + 1);// restart means new term SetState(RaftEngineState.Leader); } else { SetState(RaftEngineState.Follower); } _eventLoopTask = Task.Factory.StartNew(EventLoop, TaskCreationOptions.LongRunning); }
public void AllPeers_and_AllVotingPeers_can_be_persistantly_saved_and_loaded() { var cancellationTokenSource = new CancellationTokenSource(); var path = "test" + Guid.NewGuid(); try { var expectedAllVotingPeers = new List <string> { "Node123", "Node1", "Node2", "NodeG", "NodeB", "NodeABC" }; using (var options = StorageEnvironmentOptions.ForPath(path)) { using (var persistentState = new PersistentState("self", options, cancellationTokenSource.Token) { CommandSerializer = new JsonCommandSerializer() }) { var currentConfiguration = persistentState.GetCurrentTopology(); Assert.Empty(currentConfiguration.AllVotingNodes); var currentTopology = new Topology(new Guid("355a589b-cadc-463d-a515-5add2ea47205"), expectedAllVotingPeers.Select(x => new NodeConnectionInfo { Name = x }), Enumerable.Empty <NodeConnectionInfo>(), Enumerable.Empty <NodeConnectionInfo>()); persistentState.SetCurrentTopology(currentTopology, 1); } } using (var options = StorageEnvironmentOptions.ForPath(path)) { using (var persistentState = new PersistentState("self", options, cancellationTokenSource.Token) { CommandSerializer = new JsonCommandSerializer() }) { var currentConfiguration = persistentState.GetCurrentTopology(); Assert.Equal(expectedAllVotingPeers.Count, currentConfiguration.AllVotingNodes.Count()); foreach (var nodeConnectionInfo in currentConfiguration.AllVotingNodes) { Assert.True(expectedAllVotingPeers.Contains(nodeConnectionInfo.Name)); } } } } finally { new DirectoryInfo(path).Delete(true); } }
public RaftEngine(RaftEngineOptions raftEngineOptions) { //#if DEBUG // Console.WriteLine("Press any key to continue loading Raft -> opportunity to attach debugger"); // Console.ReadLine(); //#endif _raftEngineOptions = raftEngineOptions; Debug.Assert(raftEngineOptions.Stopwatch != null); _log = LogManager.GetLogger(raftEngineOptions.Name + "." + GetType().FullName); _eventLoopCancellationTokenSource = new CancellationTokenSource(); Name = raftEngineOptions.Name; PersistentState = new PersistentState(raftEngineOptions.Name, raftEngineOptions.StorageOptions, _eventLoopCancellationTokenSource.Token) { CommandSerializer = new JsonCommandSerializer() }; _currentTopology = PersistentState.GetCurrentTopology(); //warm up to make sure that the serializer don't take too long and force election timeout PersistentState.CommandSerializer.Serialize(new NopCommand()); var thereAreOthersInTheCluster = CurrentTopology.QuorumSize > 1; if (thereAreOthersInTheCluster == false && CurrentTopology.IsVoter(Name)) { PersistentState.UpdateTermTo(this, PersistentState.CurrentTerm + 1); // restart means new term SetState(RaftEngineState.Leader); } else { SetState(RaftEngineState.Follower); } _commitIndex = StateMachine.LastAppliedIndex; _eventLoopTask = Task.Run(() => EventLoop()); }