public void become_follower_with_term_reduction_is_fatal() { var audit = new Mock <IAuditLog>(); var planner = new Mock <IPlanner>(); using (var server = new RaftServer("a", audit.Object, planner.Object)) { server.BecomeFollower(2); Assert.That(() => server.BecomeFollower(1), Throws.Exception); } }
public void become_follower_updates_term() { var audit = new Mock <IAuditLog>(); var planner = new Mock <IPlanner>(); using (var server = new RaftServer("a", audit.Object, planner.Object)) { server.BecomeFollower(2); Assert.AreEqual(2, server.CurrentTerm); } }
public void become_follower_leads_to_become_candidate() { var audit = new Mock <IAuditLog>(); var planner = new Mock <IPlanner>(); using (var server = new RaftServer("a", audit.Object, planner.Object)) { var t = server.BecomeFollower(2); t.Wait(2000); Assert.AreEqual(1, 1); } }
public override async void Execute(RaftServer server, bool AsLeader) { lock (server) { server.HasGameStarted = false; server.GameStartRequest = false; server.SessionClientsAddress = new List <Uri>(); //send end to all clients in game } //sending info to clients if (AsLeader) { foreach (IClient client in server.SessionClients) { await Task.Run(() => { try { client.End(server.StateMachine.GetTopPlayer()); } catch (Exception ee) { } ; }); } } lock (server) { server.SessionClients = new List <IClient>(); if (AsLeader) { if (!server.HasGameStarted && !server.GameStartRequest && server.PendingClients.Count >= server.NumPlayers) { StartCommand startCommand = new StartCommand() { Name = "Start" }; bool response; int commitAt; server.OnCommand(startCommand); } } } }
public override void Execute(RaftServer server, bool AsLeader) { Console.WriteLine("Join Commited."); IClient client = (IClient)Activator.GetObject( typeof(IClient), address.ToString() + "Client"); server.PendingClients.Add(client); Console.WriteLine("ADDDED NOW PENDING: " + server.PendingClients.Count); if (AsLeader) { Console.WriteLine("AS LEADER"); //Have enough players if (!server.HasGameStarted && !server.GameStartRequest && server.PendingClients.Count >= server.NumPlayers) { server.GameStartRequest = true; // this is used to make sure no more startgame logs are created before the startgame entry is commited //Make start Log StartCommand startCommand = new StartCommand() { Name = "Start" }; bool accepted; int commitedAt; server.OnCommand(startCommand); /* * if (server.PeerURIs.Count == 1) * { * //I'm the only one, I can commit everything * server.CommitIndex = server.Log.Count - 1; * Task.Run(() => server.StateMachine(server.Log[server.CommitIndex].Command)); * }*/ //Task.Run(() => server.OnHeartbeatTimerOrSendTrigger()); } } }
static void Main(string[] args) { Console.WriteLine(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond); Console.ReadLine(); Uri r1URI = new Uri("tcp://127.0.0.1:50006"); Uri r2URI = new Uri("tcp://127.0.0.1:50007"); Uri r3URI = new Uri("tcp://127.0.0.1:50008"); RaftServer r1 = new RaftServer(r1URI, 1, 20); RaftServer r2 = new RaftServer(r2URI, 1, 20); RaftServer r3 = new RaftServer(r3URI, 1, 20); List <Uri> list = new List <Uri>(); list.Add(r1URI); list.Add(r2URI); list.Add(r3URI); r1.Start(list); r2.Start(list); r3.Start(list); Task.Run(() => { Uri clientURL = new Uri("tcp://127.0.0.1:50009"); Hub hub = new Hub(list, clientURL, new SimpleGame()); hub.OnStart += (stage) => { global::System.Console.WriteLine("GAME STARTING IN CLIENT"); }; try { JoinResult result = hub.Join("TESTE"); } catch (InvalidUsernameException exc) { } }); /* * Timer tmr = new Timer(); * * tmr.Interval = 5000; // 0.1 second * tmr.Elapsed += (object sender, ElapsedEventArgs e) => * { * bool accepted; * int commitedAt; * r1.OnCommand(new RaftCommand() { Name = "TEste1" }, out accepted, out commitedAt); * r2.OnCommand(new RaftCommand() { Name = "TEste2" }, out accepted, out commitedAt); * r3.OnCommand(new RaftCommand() { Name = "TEste3" }, out accepted, out commitedAt); * r1.OnCommand(new RaftCommand() { Name = "TEste4" }, out accepted, out commitedAt); * r2.OnCommand(new RaftCommand() { Name = "TEste5" }, out accepted, out commitedAt); * r3.OnCommand(new RaftCommand() { Name = "TEste6" }, out accepted, out commitedAt); * }; // We'll write it in a bit * * tmr.Start(); // The countdown is launched! */ /* Uri uri = new Uri(); * Server.Server server = new Server.Server(); * Server.Server server2 = new Server.Server(new Uri("tcp:3002"), new Uri("tcp:3001")); * Server.Server server3 = new Server.Server(new Uri("tcp:3003"), new Uri("tcp:3001")); * Console.ReadLine();*/ Console.ReadLine(); }
public override void Execute(RaftServer server, bool AsLeader) { server.plays[Address] = Play; }
public override void Execute(RaftServer server, bool AsLeader) { server.GameStartRequest = false; //request fullfilled Console.WriteLine("Game start commited. AsLeader: " + AsLeader); //In the leader it might be necessary to lock try { foreach (IClient client2 in server.PendingClients) { Console.WriteLine($"pending {client2.Address}"); } server.SessionClients = server.PendingClients.Take(server.NumPlayers).ToList(); //get the first N clients server.PendingClients = server.PendingClients.Skip(server.NumPlayers).ToList(); server.PlayerList = new List <IPlayer>(); Console.WriteLine($"Numplayers {server.NumPlayers}"); //Console.WriteLine(System.Environment.StackTrace); server.HasGameStarted = true; foreach (IClient client2 in server.SessionClients) { server.SessionClientsAddress.Add(client2.Address); Console.WriteLine($"Address session players {client2.Address}"); IPlayer player = new Player(); player.Address = client2.Address; player.Alive = true; player.Score = 0; player.Username = client2.Username; server.PlayerList.Add(player); } Console.WriteLine("Creating State Machine"); server.StateMachine = new GameStateMachine(server.NumPlayers, server.PlayerList); if (AsLeader) { Console.WriteLine("Contacting Clients"); //Broadcast the start signal to the client Dictionary <string, Uri> clientsP2P = new Dictionary <string, Uri>(); foreach (IClient c in server.SessionClients) { clientsP2P[c.Username] = c.Address; } //Communication with the client must be done with the leader for (int i = server.SessionClients.Count - 1; i >= 0; i--) { try { IClient client2 = server.SessionClients.ElementAt(i); client2.Start(server.StateMachine.Stage); //Signal the start client2.SetPeers(clientsP2P); //Set the Peers for the P2P chat } catch (Exception e) { Console.WriteLine(e); //server.SessionClients.RemoveAt(i); //todo : maybe remove from the whole list of clients // todo: try to reach the client again. Uma thread à parte. Verificar se faz sentido. } } //Start the game timer server.RoundTimer.AutoReset = false; server.RoundTimer.Start(); } } catch (Exception ex) { Console.WriteLine(ex); } }
public async override void Execute(RaftServer server, bool AsLeader) { // Console.WriteLine("number players:" + server.StateMachine.Stage.GetPlayers().Count); foreach (Uri address in server.plays.Keys) { IPlayer player = server.StateMachine .Stage.GetPlayers().First(p => p.Address.ToString() == address.ToString()); server.StateMachine.SetPlay(player, server.plays[address]); } server.plays.Clear(); List <Shared.Action> actionList = server.StateMachine.NextRound(); if (AsLeader) { if (server.SessionClients.Count == 0) { foreach (Uri uri in server.SessionClientsAddress) { IClient client = (IClient)Activator.GetObject( typeof(IClient), uri.ToString() + "Client"); server.SessionClients.Add(client); } } Console.WriteLine("EXECUTE ROUND AS LEADER"); for (int i = server.SessionClients.Count - 1; i >= 0; i--) { await Task.Run(() => { IClient client; try { client = server.SessionClients[i]; Console.WriteLine(actionList); Console.WriteLine(server.PlayerList); Console.WriteLine(server.StateMachine.Round); Console.WriteLine(server.Address); client.SendRound(actionList, server.PlayerList, server.StateMachine.Round, server.Address.ToString()); // Console.WriteLine(String.Format("Sending stage to client: {0}, at: {1}", client.Username, client.Address)); // Console.WriteLine(String.Format("Round Nº{0}", server.StateMachine.Round)); } catch (Exception ex) { Console.WriteLine("CANT CONTACT CLIENT" + ex); //server.SessionClients.RemoveAt(i); // todo: try to reach the client again. Uma thread à parte. Verificar se faz sentido. /*todo: * qual a estrategia a adoptar aqui para tentar reconectar com o cliente? * * Dectar falhas de clientes, lidar com falsos positivos. * * Caso não seja pssível contactar o cliente, na próxima ronda deve de ir uma acção em que o player * está morto, e deve ser removido do jogo. * E deve ser apresentado no chat UMA MENSAGEM no chat a indicar que o jogador saiu do jogo * * garantimos a possibilidade de um cliente voltar a entrar no jogo? * */ } }); } } server.RoundTimer.Start(); //Start the timer }