public override EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { lock (vote_heartbeat_Lock) { Console.WriteLine("heartbeat"); //Console.WriteLine("Candidate: AppendEntryWrite from: " + leaderID); if (term < _term) { //TODO return(new EntryResponse(false, _term, _server.getLogIndex())); } else { _term = term; Console.WriteLine("Leader changed to: " + leaderID); if (entryPacket.Count == 0) { timerThreadBlock = true; _server.updateState("follower", _term, leaderID); _server = null; electionTimeout.Dispose(); return(new EntryResponse(true, _term, _server.getLogIndex())); } if ((_server.getLogIndex() - 1 + entryPacket.Count) != entryPacket.Entrys[entryPacket.Count - 1].LogIndex) { //envio o server log index e isso diz quantas entrys tem o log, do lado de la, ele ve Console.WriteLine("Candidate -> Follower : appendEntry "); timerThreadBlock = true; _server.updateState("follower", _term, leaderID); _server = null; electionTimeout.Dispose(); return(new EntryResponse(false, _term, _server.getLogIndex())); } foreach (Entry entry in entryPacket.Entrys) { _server.addEntrytoLog(entry); //TODO, matilde queres meter a comparacao de strings como gostas? xD if (entry.Type == "write") { _server.writeLeader(entry.Tuple); } else { _server.takeLeader(entry.Tuple); } } Console.WriteLine("Candidate -> Follower : append Entry"); timerThreadBlock = true; _server.updateState("follower", _term, leaderID); _server = null; electionTimeout.Dispose(); return(new EntryResponse(true, _term, _server.getLogIndex())); } } }
public override EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { lock (vote_heartbeat_Lock) { if (term < _term) { return(new EntryResponse(false, _term, _server.getLogIndex())); } else { _term = term; Console.WriteLine("Leader changed to: " + leaderID); if (entryPacket.Count == 0) { timerThreadBlock = true; stopClock(); _server.updateState("follower", _term, leaderID); _server = null; return(new EntryResponse(true, _term, _server.getLogIndex())); } if ((_server.getLogIndex() - 1 + entryPacket.Count) != entryPacket.Entrys[entryPacket.Count - 1].LogIndex) { //envio o server log index e isso diz quantas entrys tem o log, do lado de la, ele ve timerThreadBlock = true; stopClock(); _server.updateState("follower", _term, leaderID); _server = null; return(new EntryResponse(false, _term, _server.getLogIndex())); } foreach (Entry entry in entryPacket.Entrys) { if (entry.Type == "write") { _server.addEntrytoLog(entry); _server.writeLeader(entry.Tuple); } else { _server.takeLeader(entry.Tuple, entry.Term); } } timerThreadBlock = true; stopClock(); _server.updateState("follower", _term, leaderID); _server = null; return(new EntryResponse(true, _term, _server.getLogIndex())); } } }
public override EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { lock (vote_heartbeat_Lock) { if (_term < term) { _term = term; Console.WriteLine("Leader: AppendEntry from: " + leaderID); //TODO PEDIR AO SOUSA PARA EXPLICAR, FOLHA DO MARCO if ((_server.getLogIndex() - 1 + entryPacket.Count) != entryPacket.Entrys[entryPacket.Count - 1].LogIndex) { //envio o server log index e isso diz quantas entrys tem o log, do lado de la, ele ve Console.WriteLine("Leader -> Follower : appendEntry"); _server.updateState("follower", _term, leaderID); _server = null; timer.Dispose(); timerThreadBlock = true; return(new EntryResponse(false, _term, _server.getLogIndex())); } foreach (Entry entry in entryPacket.Entrys) { _server.addEntrytoLog(entry); //TODO, matilde queres meter a comparacao de strings como gostas? xD if (entry.Type == "write") { _server.writeLeader(entry.Tuple); } else { _server.takeLeader(entry.Tuple); } } Console.WriteLine("Leader -> Follower : appendEntry"); timerThreadBlock = true; _server.updateState("follower", _term, leaderID); _server = null; timer.Dispose(); //envio o server log index porque quando o servidor me enviar isto ele ja vai ter adicionado ao log dele //logo na resposta vou comparar _server.logIndex do lado de lado com o deste //na verdade o que estao a ver e: se deu true, entao eu tenho tantas packets como quem me respondeu //se bem que visto que esta true ele n vai verificar nada do log index ou term return(new EntryResponse(true, _term, _server.getLogIndex())); } return(new EntryResponse(false, _term, _server.getLogIndex())); } }
public override EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { lock (vote_heartbeat_Lock) { if (term < _term) { //o pedido que recebi e de um lider que ficou para tras //apenas no unperfect return(new EntryResponse(false, _term, _server.getLogIndex())); } else { try { if (!electionTimeout.Enabled) //caso em que timer acabou durante o processamento de um heartbeat { timerThreadBlock = true; } stopClock(); if (entryPacket.Count == 0) { if (leaderID != _leaderUrl) { _leaderUrl = leaderID; _leaderRemote = _server.serverRemoteObjects[_leaderUrl]; Console.WriteLine("Follower: Leader is now: " + leaderID); } return(new EntryResponse(true, _term, _server.getLogIndex())); } _term = term; //pode ser != mas visto que se tiver desatualizado e para tras if ((_server.getLogIndex() - 1 + entryPacket.Count) == entryPacket.Entrys[entryPacket.Count - 1].LogIndex) { //envio o server log index e isso diz quantas entrys tem o log, do lado de la, ele ve //Treasts case of leader changed if (leaderID != _leaderUrl) { _leaderUrl = leaderID; _leaderRemote = _server.serverRemoteObjects[_leaderUrl]; Console.WriteLine("Follower: Leader is now: " + leaderID); } foreach (Entry entry in entryPacket.Entrys) { if (entry.Type == "write") { _server.addEntrytoLog(entry); _server.writeLeader(entry.Tuple); } else { _server.takeLeader(entry.Tuple, entry.Term); } } return(new EntryResponse(true, _term, _server.getLogIndex())); } else { //manda apenas o log index porque assim o server vai saber quantas entrys no log do follower estao return(new EntryResponse(false, _term, _server.getLogIndex())); } } finally { SetTimer(); } } } }
public EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { return(_state.appendEntry(entryPacket, term, leaderID)); }
public void pulseAppendEntry() { if (timerThreadBlock) { return; } int sucess = 1; timer.Enabled = true; if (_server.fd.changed()) { _view = _server.fd.getView(); _numServers = _view.Count(); } Dictionary <int, string> i_url_map = new Dictionary <int, string>(); WaitHandle[] handles = new WaitHandle[_numServers - 1]; IAsyncResult[] asyncResults = new IAsyncResult[_numServers - 1]; try { int i = 0; foreach (string url in _view) { if (url == _url) { continue; } EntryPacket entryPacket = new EntryPacket(); int theirIndex = _server.matchIndexMap[url]; int myindex = _server.getLogIndex(); if (myindex != theirIndex) { for (int k = theirIndex; k < myindex; k++) { entryPacket.Add(_server.entryLog[k]); } } ServerService remoteObject = (ServerService)_serverRemoteObjects[url]; appendEntryDelegate appendEntryDel = new appendEntryDelegate(remoteObject.appendEntry); IAsyncResult ar = appendEntryDel.BeginInvoke(entryPacket, _term, _url, null, null); asyncResults[i] = ar; handles[i] = ar.AsyncWaitHandle; i_url_map.Add(i, url); i++; } if (!WaitHandle.WaitAll(handles, 5000)) //TODO esta desoncronizado { pulseHeartbeat(); } else { foreach (KeyValuePair <int, string> entry in i_url_map) { IAsyncResult asyncResult = asyncResults[entry.Key]; appendEntryDelegate appendEntryDel = (appendEntryDelegate)((AsyncResult)asyncResult).AsyncDelegate; EntryResponse response = appendEntryDel.EndInvoke(asyncResult); if (!response.Sucess) //foi false { if (_term < response.Term) //term da resposta e maior do que o meu { Console.WriteLine("Leader -> Follower : pulseappendEntry"); timerThreadBlock = true; _server.updateState("follower", _term, response.Leader); _server = null; timer.Dispose(); } //nao estou a tratar quando da false por causa do log aqui especificamente //trato tudo da mesma maneira } //se tiver ter dado true e porque os 2 estao up to date, logo atualizo o dele para o bem //se tiver dado false, meto no mapa nao contando para os sucessos, //depois no heartbeat a seguir deve sincronizar teoricamente :) _server.matchIndexMap[entry.Value] = response.MatchIndex; if (response.Sucess) { sucess++; } } if (!(sucess > (_numServers / 2))) { pulseAppendEntry(); } } } catch (ElectionException) { //nao sei se e preciso tratar visto que nao pode existir 1 lider e 1 candidato ao mesmo tempo } catch (SocketException) { //TODO throw new NotImplementedException(); } }
public abstract EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID);
public EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { _server.checkFrozen(); return(_server.appendEntry(entryPacket, term, leaderID)); }
public override EntryResponse appendEntry(EntryPacket entryPacket, int term, string leaderID) { lock (vote_heartbeat_Lock) { //Console.WriteLine("heartbeat"); if (term < _term) { //o pedido que recebi e de um lider que ficou para tras //apenas no unperfect Console.WriteLine("Returned false because term of leader is lower"); return(new EntryResponse(false, _term, _server.getLogIndex())); } else { try { if (!electionTimeout.Enabled) //caso em que timer acabou durante o processamento de um heartbeat { timerThreadBlock = true; } else { electionTimeout.Stop(); } electionTimeout.Interval = wait; if (entryPacket.Count == 0) { if (leaderID != _leaderUrl) { _leaderUrl = leaderID; _leaderRemote = _server.serverRemoteObjects[_leaderUrl]; //Console.WriteLine("Follower: Leader is now: " + leaderID); } return(new EntryResponse(true, _term, _server.getLogIndex())); } Console.WriteLine("UPDATE TERM IN APPEND ENTRY"); _term = term; //pode ser != mas visto que se tiver desatualizado e para tras if ((_server.getLogIndex() - 1 + entryPacket.Count) == entryPacket.Entrys[entryPacket.Count - 1].LogIndex) { //envio o server log index e isso diz quantas entrys tem o log, do lado de la, ele ve //Treasts case of leader changed if (leaderID != _leaderUrl) { _leaderUrl = leaderID; _leaderRemote = _server.serverRemoteObjects[_leaderUrl]; Console.WriteLine("Follower: Leader is now: " + leaderID); } foreach (Entry entry in entryPacket.Entrys) { _server.addEntrytoLog(entry); //TODO, matilde queres meter a comparacao de strings como gostas? xD if (entry.Type == "write") { _server.writeLeader(entry.Tuple); } else { _server.takeLeader(entry.Tuple); } } return(new EntryResponse(true, _term, _server.getLogIndex())); } else { Console.WriteLine("Rejected entry because i am not up do date"); //manda apenas o log index porque assim o server vai saber quantas entrys no log do follower estao return(new EntryResponse(false, _term, _server.getLogIndex())); } } finally { electionTimeout.Start(); } } } }