public StateLogEntrySuggestion GetNextStateLogEntrySuggestion(StateLogEntryRequest req) { StateLogEntrySuggestion le = new StateLogEntrySuggestion() { LeaderTerm = this.stateMachine.NodeTerm }; ulong prevId = 0; ulong prevTerm = 0; StateLogEntry entry = null; if (req.StateLogEntryId == 0) { //send first record to sync var key = GetKey(0, 0); Slice value; var iter = db.NewIterator(ReadOptions.Default); iter.Seek(key); iter.Next(); while (iter.Valid()) { entry = StateLogEntry.BiserDecode(value.ToArray()); if (entry.IsCommitted) { break; } iter.Next(); } } else { var key = GetKey(req.StateLogEntryTerm, req.StateLogEntryId); Slice value; var iter = db.NewIterator(ReadOptions.Default); iter.Seek(key); var lastOne = iter.Value(); iter.Next(); while (iter.Valid()) { entry = StateLogEntry.BiserDecode(value.ToArray()); if (entry.Index > req.StateLogEntryId) { var oldEntry = StateLogEntry.BiserDecode(lastOne.ToArray()); prevId = oldEntry.Index; prevTerm = oldEntry.Term; } } } if (entry != null) { le.StateLogEntry = entry; entry.PreviousStateLogId = prevId; entry.PreviousStateLogTerm = prevTerm; le.IsCommitted = entry.IsCommitted; return(le); } else { return(null); } }
public void AddLogEntryByFollower(StateLogEntrySuggestion suggestion) { this.log.AddLogEntryByFollower(suggestion); if (suggestion.IsCommitted) { this.stateMachine.logHandler.Commited(); } if (stateMachine.States.LeaderHeartbeat != null && log.LastCommittedIndex < stateMachine.States.LeaderHeartbeat.LastStateLogCommittedIndex) { stateMachine.SyncronizeWithLeader(true); } else { stateMachine.States.LeaderSynchronizationIsActive = false; } if (stateMachine.States.LeaderHeartbeat != null && log.LastCommittedIndex < stateMachine.States.LeaderHeartbeat.LastStateLogCommittedIndex) { stateMachine.SyncronizeWithLeader(true); } else { stateMachine.States.LeaderSynchronizationIsActive = false; } }
/// <summary> /// + /// Can be null. /// Must be called inside of operation lock. /// </summary> /// <param name="logEntryId"></param> /// <param name="LeaderTerm"></param> /// <returns></returns> public StateLogEntrySuggestion GetNextStateLogEntrySuggestionFromRequested(StateLogEntryRequest req) { StateLogEntrySuggestion le = new StateLogEntrySuggestion() { LeaderTerm = rn.NodeTerm }; return(le); }
public void AddLogEntry(StateLogEntrySuggestion suggestion) { PreviousStateLogId = suggestion.StateLogEntry.PreviousStateLogId; PreviousStateLogTerm = suggestion.StateLogEntry.PreviousStateLogTerm; StateLogId = suggestion.StateLogEntry.Index; StateLogTerm = suggestion.StateLogEntry.Term; if (list.Exists(s => s.Index == suggestion.StateLogEntry.Index && s.Term == suggestion.StateLogEntry.Term)) { var oldValue = list.Find(s => s.Index == suggestion.StateLogEntry.Index); oldValue.IsCommitted = suggestion.IsCommitted; } else { this.list.Add(suggestion.StateLogEntry); } }
public StateLogEntrySuggestion GetNextStateLogEntrySuggestion(StateLogEntryRequest req) { StateLogEntrySuggestion le = new StateLogEntrySuggestion() { LeaderTerm = this.stateMachine.NodeTerm }; ulong prevId = 0; ulong prevTerm = 0; StateLogEntry entry = null; if (req.StateLogEntryId == 0) { //send first record to sync entry = list.Find(s => s.IsCommitted == true); } else { for (int index = 0; index < list.Count; index++) { if (list[index].Index > req.StateLogEntryId) { //find next one and set preview value if (index > 0) { prevId = list[index - 1].Index; prevTerm = list[index - 1].Term; entry = list[index]; break; } } } } if (entry != null) { le.StateLogEntry = entry; entry.PreviousStateLogId = prevId; entry.PreviousStateLogTerm = prevTerm; le.IsCommitted = entry.IsCommitted; return(le); } else { return(null); } }
public void AddLogEntryByFollower(StateLogEntrySuggestion suggestion) { //remove all log bigger than this,(clear no committed logs) var key = GetKey(suggestion.StateLogEntry.Term, suggestion.StateLogEntry.Index); var iter = db.NewIterator(); iter.Seek(key); while (iter.Valid()) { iter.Next(); if (iter.Valid()) { db.Remove(iter.Key()); } else { break; } } //add this one AddLogEntry(suggestion); //update commit status if (suggestion.IsCommitted) { if (this.LastCommittedIndexTerm > suggestion.StateLogEntry.Term || ( this.LastCommittedIndexTerm == suggestion.StateLogEntry.Term && this.LastCommittedIndex > suggestion.StateLogEntry.Index )) { //Should be not possible } else { this.LastCommittedIndex = suggestion.StateLogEntry.Index; this.LastCommittedIndexTerm = suggestion.StateLogEntry.Term; } } }
public void AddLogEntry(StateLogEntrySuggestion suggestion) { PreviousStateLogId = suggestion.StateLogEntry.PreviousStateLogId; PreviousStateLogTerm = suggestion.StateLogEntry.PreviousStateLogTerm; StateLogId = suggestion.StateLogEntry.Index; StateLogTerm = suggestion.StateLogEntry.Term; var key = GetKey(suggestion.StateLogEntry.Term, suggestion.StateLogEntry.Index); var value = db.Get(key); var find = value != null; if (find) { var entry = StateLogEntry.BiserDecode(value); entry.IsCommitted = suggestion.IsCommitted; value = entry.BiserEncoder().Encode(); db.Put(key, value); } else { var data = suggestion.StateLogEntry.BiserEncode(); db.Put(key, data); } }
public void AddLogEntry(StateLogEntrySuggestion suggestion) { PreviousStateLogId = suggestion.StateLogEntry.PreviousStateLogId; PreviousStateLogTerm = suggestion.StateLogEntry.PreviousStateLogTerm; StateLogId = suggestion.StateLogEntry.Index; StateLogTerm = suggestion.StateLogEntry.Term; var key = GetKey(suggestion.StateLogEntry.Term, suggestion.StateLogEntry.Index); Slice value; var find = db.TryGet(ReadOptions.Default, (Slice)key, out value); if (find) { var entry = StateLogEntry.BiserDecode(value.ToArray()); entry.IsCommitted = suggestion.IsCommitted; value = (Slice)entry.BiserEncoder().Encode(); db.Put(WriteOptions.Default, key, value); } else { var data = suggestion.StateLogEntry.BiserEncode(); db.Put(WriteOptions.Default, key, (Slice)data); } }
public void AddLogEntryByFollower(StateLogEntrySuggestion suggestion) { //remove all log bigger than this,(clear no committed logs) list.RemoveAll(s => s.Term >= suggestion.StateLogEntry.Term || s.Index > suggestion.LeaderTerm); //add this one AddLogEntry(suggestion); //update commit status if (suggestion.IsCommitted) { if (this.LastCommittedIndexTerm > suggestion.StateLogEntry.Term || ( this.LastCommittedIndexTerm == suggestion.StateLogEntry.Term && this.LastCommittedIndex > suggestion.StateLogEntry.Index )) { //Should be not possible } else { this.LastCommittedIndex = suggestion.StateLogEntry.Index; this.LastCommittedIndexTerm = suggestion.StateLogEntry.Term; } } }
public async Task OnRecieve(IChannelHandlerContext context, string msgstr) { // if (!string.IsNullOrEmpty(msgstr)) { //RaftCommand msgObj = Newtonsoft.Json.JsonConvert.DeserializeObject<RaftCommand>(msgstr, new JsonSerializerSettings() //{ // NullValueHandling = NullValueHandling.Ignore, // TypeNameHandling = TypeNameHandling.All, // TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full //} //); int index = msgstr.IndexOf(','); string num = msgstr.Substring(0, index); string base64 = msgstr.Substring(index + 1); byte[] data = Convert.FromBase64String(base64); RaftCommand cmd = new RaftCommand(); cmd.Code = Convert.ToInt32(num); switch (cmd.Code) { case RaftCommand.Handshake: cmd.Message = TcpMsgHandshake.BiserDecode(data); break; case RaftCommand.HandshakeACK: cmd.Message = TcpMsgHandshake.BiserDecode(data); break; case RaftCommand.RaftMessage: cmd.Message = TcpMsgRaft.BiserDecode(data); TcpMsgRaft t = (TcpMsgRaft)cmd.Message; switch (t.RaftSignalType) { case eRaftSignalType.LeaderHearthbeat: t.orginalObject = LeaderHeartbeat.BiserDecode(t.Data); break; case eRaftSignalType.CandidateRequest: t.orginalObject = CandidateRequest.BiserDecode(t.Data); break; case eRaftSignalType.StateLogEntryAccepted: t.orginalObject = StateLogEntryApplied.BiserDecode(t.Data); break; case eRaftSignalType.StateLogEntryRequest: t.orginalObject = StateLogEntryRequest.BiserDecode(t.Data); break; case eRaftSignalType.StateLogEntrySuggestion: t.orginalObject = StateLogEntrySuggestion.BiserDecode(t.Data); break; case eRaftSignalType.StateLogRedirectRequest: t.orginalObject = StateLogEntryRedirectRequest.BiserDecode(t.Data); break; case eRaftSignalType.VoteOfCandidate: t.orginalObject = VoteOfCandidate.BiserDecode(t.Data); break; } break; case RaftCommand.FreeMessage: cmd.Message = TcpMsg.BiserDecode(data); break; } this.packetParser(cmd as RaftCommand); } }
/// <summary> /// /// </summary> /// <param name="suggestion"></param> /// <returns></returns> public void AddToLogFollower(StateLogEntrySuggestion suggestion) { try { int pups = 0; lock (inMem.Sync) { List <Tuple <ulong, ulong, StateLogEntry> > toDelete = new List <Tuple <ulong, ulong, StateLogEntry> >(); foreach (var el in inMem.SelectForwardFromTo(suggestion.StateLogEntry.Index, ulong.MinValue, true, ulong.MaxValue, ulong.MaxValue)) { if (el.Item1 == suggestion.StateLogEntry.Index && el.Item2 == suggestion.StateLogEntry.Term) { if (pups > 0) { //!!!!!!!!!!!!!!! note, to be checked, it returns, but may be it could have smth to remove before (earlier term - ulong.MinValue is used ) throw new Exception("Pups more than 0"); } return; } toDelete.Add(el); pups++; } if (toDelete.Count > 0) { inMem.Remove(toDelete); } inMem.Add(suggestion.StateLogEntry.Index, suggestion.StateLogEntry.Term, suggestion.StateLogEntry); } // rn.VerbosePrint($"{rn.NodeAddress.NodeAddressId}> AddToLogFollower (I/T): {suggestion.StateLogEntry.Index}/{suggestion.StateLogEntry.Term} -> Result:" + // $" { (GetEntryByIndexTerm(suggestion.StateLogEntry.Index, suggestion.StateLogEntry.Term) != null)};"); //Setting new internal LogId this.leaderState.tempPrevStateLogId = StateLogId; this.leaderState.tempPrevStateLogTerm = StateLogTerm; StateLogId = suggestion.StateLogEntry.Index; StateLogTerm = suggestion.StateLogEntry.Term; //tempPrevStateLogId = PreviousStateLogId; //tempPrevStateLogTerm = PreviousStateLogTerm; this.leaderState.tempStateLogId = StateLogId; this.leaderState.tempStateLogTerm = StateLogTerm; if (suggestion.IsCommitted) { if ( this.LastCommittedIndexTerm > suggestion.StateLogEntry.Term || ( this.LastCommittedIndexTerm == suggestion.StateLogEntry.Term && this.LastCommittedIndex > suggestion.StateLogEntry.Index ) ) { //Should be not possible } else { this.LastCommittedIndex = suggestion.StateLogEntry.Index; this.LastCommittedIndexTerm = suggestion.StateLogEntry.Term; //this.rn.Commited(suggestion.StateLogEntry.Index); this.rn.logHandler.Commited(); } } } catch (Exception ex) { } //if (this.LastCommittedIndex < rn.LeaderHeartbeat.LastStateLogCommittedIndex) if (rn.States.LeaderHeartbeat != null && this.LastCommittedIndex < rn.States.LeaderHeartbeat.LastStateLogCommittedIndex) { rn.SyncronizeWithLeader(true); } else { LeaderSynchronizationIsActive = false; } }
static void t2() { /* * Start * Protobuf obj length: 28 * Biser Binary obj length: 20 * NetJson obj length: 182 * Biser Json obj length: 182 * * Protobuf encode: 1367 ms * Protobuf decode: 1909 ms * Biser Binary encode: 464 ms * Biser Binary decode: 271 ms * NetJson encode: 1687 ms * NetJson decode: 2383 ms * Biser Json encode: 2871 ms * Biser Json decode: 4748 ms * Press any key */ System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); // It's an operational class from https://github.com/hhblaze/Raft.Net/blob/master/Raft/StateMachine/StateLogEntry.cs StateLogEntry sle = new StateLogEntry() { Data = new byte[] { 1, 2, 3, 4, 5 }, Index = 458, IsCommitted = true, PreviousStateLogId = 4789, PreviousStateLogTerm = 447, RedirectId = 12, Term = 99 }; // It's an operational class from https://github.com/hhblaze/Raft.Net/blob/master/Raft/Objects/StateLogEntrySuggestion.cs StateLogEntrySuggestion obj = new StateLogEntrySuggestion() { IsCommitted = true, LeaderTerm = 77, StateLogEntry = sle }; Console.WriteLine("t2----------------------------------"); //Protobuf. Warming up, getting length var pBt = obj.SerializeProtobuf(); Console.WriteLine($"Protobuf obj length: {pBt.Length}"); var pObj = pBt.DeserializeProtobuf <StateLogEntrySuggestion>(); //Biser. Getting length var bBt = new Biser.Encoder().Add(obj).Encode(); Console.WriteLine($"Biser Binary obj length: {bBt.Length}"); var bObj = StateLogEntry.BiserDecode(bBt); //NetJson. Getting length var njss = NetJSON.NetJSON.Serialize(obj); Console.WriteLine($"NetJson obj length: {System.Text.Encoding.UTF8.GetBytes(njss).Length}"); var bnjss = NetJSON.NetJSON.Deserialize <StateLogEntrySuggestion>(njss); //Biser Json. Getting length var bjss = new Biser.JsonEncoder(obj).GetJSON(); Console.WriteLine($"Biser Json obj length: {System.Text.Encoding.UTF8.GetBytes(bjss).Length}"); var bbjss = StateLogEntrySuggestion.BiserJsonDecode(bjss); //Message Pack var mBt = MessagePackSerializer.Serialize(obj); Console.WriteLine($"Message Pack obj length: {mBt.Length}"); var mc2 = MessagePackSerializer.Deserialize <StateLogEntrySuggestion>(mBt); Console.WriteLine(""); byte[] tbt = null; StateLogEntrySuggestion tobj = null; sw.Start(); for (int i = 0; i < 1000000; i++) { tbt = obj.SerializeProtobuf(); } sw.Stop(); Console.WriteLine($"Protobuf encode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { tobj = pBt.DeserializeProtobuf <StateLogEntrySuggestion>(); } sw.Stop(); Console.WriteLine($"Protobuf decode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { tbt = new Biser.Encoder().Add(obj).Encode(); } sw.Stop(); Console.WriteLine($"Biser Binary encode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { tobj = StateLogEntrySuggestion.BiserDecode(bBt); } sw.Stop(); Console.WriteLine($"Biser Binary decode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { njss = NetJSON.NetJSON.Serialize(obj); } sw.Stop(); Console.WriteLine($"NetJson encode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { bnjss = NetJSON.NetJSON.Deserialize <StateLogEntrySuggestion>(njss); } sw.Stop(); Console.WriteLine($"NetJson decode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { bjss = new Biser.JsonEncoder(obj).GetJSON(); } sw.Stop(); Console.WriteLine($"Biser Json encode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { bbjss = StateLogEntrySuggestion.BiserJsonDecode(bjss); } sw.Stop(); Console.WriteLine($"Biser Json decode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { mBt = MessagePackSerializer.Serialize(obj); } sw.Stop(); Console.WriteLine($"MessagePack encode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); sw.Start(); for (int i = 0; i < 1000000; i++) { mc2 = MessagePackSerializer.Deserialize <StateLogEntrySuggestion>(mBt); } sw.Stop(); Console.WriteLine($"MessagePack decode: {sw.ElapsedMilliseconds} ms"); sw.Reset(); }