public void success() { TestContext.Progress.WriteLine("start test: success"); //ping servers Assert.True(GetServerPuppeteer(server1).ping()); Assert.True(GetServerPuppeteer(server2).ping()); //ping clients Assert.True(GetClientPuppeteer(client1).ping()); Assert.True(GetClientPuppeteer(client2).ping()); //clients create join and close meeting GetClientPuppeteer(client1).createMeeting( "create myTopic0 1 2 2 Lisboa,2020-01-02 Porto,2020-02-03 c1 c2".Split(' ')); Thread.Sleep(2000); GetClientPuppeteer(client1).join("join myTopic0 1 Lisboa,2020-01-02".Split(' ')); GetClientPuppeteer(client2).join("join myTopic0 1 Lisboa,2020-01-02".Split(' ')); Thread.Sleep(2000); GetClientPuppeteer(client1).close("myTopic0"); Thread.Sleep(3000); //Get meeting and check parameters MeetingProposal m1 = GetClientPuppeteer(client1).getMeeting("myTopic0"); MeetingProposal m2 = GetClientPuppeteer(client2).getMeeting("myTopic0"); Assert.False(m1.open); Assert.False(m2.open); TestContext.Progress.WriteLine("end test"); Assert.Pass(); }
//write meeting public void writeMeeting(MeetingProposal meeting, List <ServerInfo> servers) { if (server.freeze) { Action action = new Action(() => writeMeeting(meeting, servers)); server.actionList.Add(action); return; } Log.Debug("write meeting {topic} version {v}", meeting.topic, meeting.version); server.randomSleep(); if (server.meetingList.ContainsKey(meeting.topic) && meeting.version > server.meetingList[meeting.topic].version) { server.meetingList.Remove(meeting.topic); server.meetingList.Add(meeting.topic, meeting); server.blockedMeetings.Remove(meeting.topic); //update location's room if (meeting.room != null) { Location location = meeting.room.location; location.roomList.Remove(meeting.room.room_name); location.roomList.Add(meeting.room.room_name, meeting.room); } //Async send meeting info to clients server.updateClients(meeting); } //send broadcast to servers server.writeBroadcast(meeting, servers); }
void sendMeeting(ServerInfo serverInfo, MeetingProposal meeting, ref int consensus) { Log.Debug("sending {meeting} to {server}", meeting.topic, serverInfo.server_id); IServerToServer server = (IServerToServer)Activator.GetObject( typeof(IServerToServer), serverInfo.url_to_server); bool join = false; try{ join = server.sendMeeting(meeting); } catch (Exception ex) { Log.Error(ex, "cannot send meeting"); join = false; } if (join) { Log.Debug("{server} accepted {meeting}", serverInfo.server_id, meeting.topic); if (Interlocked.Decrement(ref consensus) == 0) { meetingLock.Set(); } } else { Log.Debug("{server} did not accept {meeting}", serverInfo.server_id, meeting.topic); } }
public void ReceiveInvitation(MeetingProposal proposal, int nClients, List <string> inviteesLeft = null) { // updates clients known if it's client count is not right if (_knownClientUrls.Count != nClients) { try { _knownClientUrls = _remoteServer.AskForUpdateClients(); UpdateClients(_knownClientUrls); } catch (Exception e) { DetectDeadServer(); SwitchServer(); _knownClientUrls = _remoteServer.AskForUpdateClients(); UpdateClients(_knownClientUrls); } } if (inviteesLeft != null) { SendInvitations(inviteesLeft, proposal); } _knownMeetingProposals.Add(proposal.Topic, proposal); Console.WriteLine("Received proposal with topic: {0}", proposal.Topic); }
//get meeting public bool sendMeeting(MeetingProposal meeting) { if (server.freeze) { return(false); } Log.Debug("received meeting {topic} version {v}", meeting.topic, meeting.version); server.randomSleep(); //check version here? if (server.meetingList.ContainsKey(meeting.topic)) { //server has meeting, check version and if meeting is blocked //FIXME > vs >= //FIXME closed vs open if (server.meetingList[meeting.topic].version >= meeting.version || server.blockedMeetings.ContainsKey(meeting.topic)) { //current meeting is newer or is blocked return(false); } } server.blockedMeetings.Add(meeting.topic, meeting); Thread t = new Thread(() => meetingTimeOut(meeting)); t.Start(); return(true); }
public void updateClients(MeetingProposal meeting) { //ver logica e enviar apenas para clientes convidados //if clientList is empty, send to all clients List <ClientInfo> senders = new List <ClientInfo>(); //remove coordinator Dictionary <string, ClientInfo> newdic = new Dictionary <string, ClientInfo>(clientList); newdic.Remove(meeting.coordinator); if (meeting.invitees.Count == 0) { senders = new List <ClientInfo>(newdic.Values); } else { foreach (String invitee in meeting.invitees) { //only send meeting if the server knows the invitee if (newdic.ContainsKey(invitee)) { senders.Add(newdic[invitee]); } } } //Async send meeting info to clients foreach (ClientInfo clientInfo in senders) { UpdateClientDelegate clientDel = new UpdateClientDelegate(updateClientAsync); clientDel.BeginInvoke(clientInfo, meeting, null, null); } }
public void ReceiveClose(MeetingProposal proposal, VectorClock newVector) { while (_isFrozen) { } Thread.Sleep(RandomIncomingMessageDelay()); Console.WriteLine("received close {0}", proposal.Topic); // UPDATE VECTOR CLOCK updateVectorClock(proposal, newVector); MeetingProposal previousProposal; if (_currentMeetingProposals.TryGetValue(proposal.Topic, out previousProposal)) { if (previousProposal.MeetingStatus == MeetingStatus.OPEN) { _currentMeetingProposals[proposal.Topic] = proposal; BroadcastClose(proposal); } } else { _currentMeetingProposals.TryAdd(proposal.Topic, proposal); } }
public void RemoteCreate(MeetingProposal proposal) { Task task = Task.Run(() => { _remoteServer.Create(proposal); }); try { task.Wait(TimeSpan.FromMilliseconds(TIMEOUT)); if (task.IsCompleted == false) { throw new TimeoutException("Timeout in remoteCreate"); } } catch (AggregateException e) { DetectDeadServer(); SwitchServer(); RemoteCreate(proposal); } catch (TimeoutException e) { DetectDeadServer(); SwitchServer(); RemoteCreate(proposal); } }
public void AddMeetingToList(MeetingProposal mp) { this.BeginInvoke(new MethodInvoker(delegate { string state = ""; if (mp.Status == MeetingProposal.StatusEnum.Open) { state = "Open"; } else if (mp.Status == MeetingProposal.StatusEnum.Closed) { state = "Closed"; } else if (mp.Status == MeetingProposal.StatusEnum.Cancelled) { state = "Cancelled"; } string bookedSlot = (mp.BookedSlot == null || mp.BookedSlot.location == null || mp.BookedSlot.location == "" ? "" : mp.BookedSlot.ToString()); string bookedRoom = (mp.BookedRoom == null || mp.BookedRoom.Name == null || mp.BookedRoom.Name == "" ? "" : mp.BookedRoom.Name); listMeetingsLv.Items.Add(new ListViewItem(new string[] { mp.Topic, mp.CoordinatorUsername, mp.MinAttendees.ToString(), state, bookedSlot, bookedRoom })); })); }
public void ReceiveJoin(string username, MeetingProposal proposal, MeetingRecord record, VectorClock newVector) { while (_isFrozen) { } Thread.Sleep(RandomIncomingMessageDelay()); updateVectorClock(proposal, newVector); Console.WriteLine("received join {0}", proposal.Topic); MeetingProposal previousProposal; if (_currentMeetingProposals.TryGetValue(proposal.Topic, out previousProposal)) { if (!previousProposal.Records.Contains(record)) //stop condition request already received { Join(username, proposal.Topic, record, local: false); } } else { _currentMeetingProposals.TryAdd(proposal.Topic, proposal); } }
public void AlreadyClose() { TestContext.Progress.WriteLine("start test: already closed"); //clients create join and close meeting GetClientPuppeteer(client1).createMeeting( "create myTopic0 2 2 0 Lisboa,2020-01-02 Porto,2020-02-03".Split(' ')); Thread.Sleep(1000); GetClientPuppeteer(client1).join("join myTopic0 1 Lisboa,2020-01-02".Split(' ')); GetClientPuppeteer(client2).join("join myTopic0 1 Lisboa,2020-01-02".Split(' ')); Thread.Sleep(1000); //primeiro close TestContext.Progress.WriteLine("1st close"); MeetingProposal m1 = GetClientPuppeteer(client1).close("myTopic0"); MeetingProposal m2 = GetClientPuppeteer(client1).getMeeting("myTopic0"); Assert.False(m1.open); Assert.False(m2.open); //tries to close meeting again TestContext.Progress.WriteLine("2nd close"); Assert.Throws(Is.TypeOf <ClientException>() .And.Message.EqualTo("cannot close meeting") .And.InnerException.InstanceOf(typeof(MeetingException)) .And.InnerException.Message.EqualTo("Meeting is already closed"), delegate { GetClientPuppeteer(client1).close("myTopic0"); }); TestContext.Progress.WriteLine("end test"); Assert.Pass(); }
public void Create(MeetingProposal proposal, string urlFailed = null) { while (_isFrozen) { } Thread.Sleep(RandomIncomingMessageDelay()); if (_currentMeetingProposals.TryAdd(proposal.Topic, proposal)) { // we create a new vector clock for the new meeting _meetingsClocks[proposal.Topic] = new VectorClock(SERVER_URL, _servers.Keys); // we create a new operations log for the new meeting _operationsLog[proposal.Topic] = new List <Operation>(); VectorClock copy = new VectorClock(_meetingsClocks[proposal.Topic]._currentVectorClock); _operationsLog[proposal.Topic].Add(new CreateOperation(copy, proposal)); Console.WriteLine("Created new meeting proposal for " + proposal.Topic + "."); BroadcastNewMeeting(proposal); } else { Console.WriteLine("Not possible to create meeting with topic {0}", proposal.Topic); } }
public void sendBroadcast(MeetingProposal meeting, ref int consensus) { foreach (KeyValuePair <string, ServerInfo> pair in serverList) { SendMeetingDelegate meetingDel = new SendMeetingDelegate(this.sendMeeting); meetingDel.BeginInvoke(pair.Value, meeting, ref consensus, null, null); } }
void DONTwriteMeeting(ServerInfo serverInfo, MeetingProposal meeting, List <ServerInfo> servers) { IServerToServer server = (IServerToServer)Activator.GetObject( typeof(IServerToServer), serverInfo.url_to_server); server.DONTwriteMeeting(meeting, servers); }
public void Create(string meetingTopic, string minAttendees, List <string> slots, List <string> invitees = null) { int timeb = DateTime.Now.Millisecond; InitClients(); List <DateLocation> parsedSlots = ParseSlots(slots); List <string> parsedInvitees = invitees; MeetingProposal proposal = new MeetingProposal { Coordinator = USERNAME, Topic = meetingTopic, MinAttendees = Int32.Parse(minAttendees), DateLocationSlots = parsedSlots, Invitees = parsedInvitees, Records = new List <MeetingRecord>(), FailedRecords = new List <MeetingRecord>(), FullRecords = new List <MeetingRecord>(), Participants = new List <string>(), MeetingStatus = MeetingStatus.OPEN }; RemoteCreate(proposal); _knownMeetingProposals.Add(proposal.Topic, proposal); int timea = DateTime.Now.Millisecond; Console.WriteLine("time passed " + (timea - timeb)); if (invitees == null) { SendInvitations(new List <string>(_clients.Keys), proposal); } else { // if coordinator is in the invitees, he takes it away because he does // not need to receive an invitation if (invitees.Contains(USERNAME)) { List <string> inviteesWithoutCoordinator = new List <string>(); foreach (string invitee in invitees) { if (!invitee.Equals(USERNAME)) { inviteesWithoutCoordinator.Add(invitee); } } SendInvitations(inviteesWithoutCoordinator, proposal); } else { SendInvitations(invitees, proposal); } } }
public void InformStateMeeting(MeetingProposal mp, MeetingProposal.StatusEnum status) { // TODO take out of closed combobox if (Client.mainForm.listMeetingPage != null) { Client.mainForm.listMeetingPage.RemoveMeetingFromList(mp); Client.mainForm.listMeetingPage.AddMeetingToList(mp); } }
private void meetingTimeOut(MeetingProposal meeting) { Thread.Sleep(5000); //if meeting ainda na blocked list and right version if (server.blockedMeetings.ContainsKey(meeting.topic) && meeting.version == server.blockedMeetings[meeting.topic].version) { server.blockedMeetings.Remove(meeting.topic); } }
public void InformStateMeeting(MeetingProposal mp) { foreach (MeetingProposal meeting in Server.meetingPropList) { if (meeting.Topic == mp.Topic) { meeting.Status = mp.Status; } } }
public Room getAvailableRoom(DateLocation finalDateLocation, MeetingProposal proposal) { if (finalDateLocation.Invitees < proposal.MinAttendees) { return(null); } Location location = _locations[finalDateLocation.LocationName]; //the final location SortedDictionary <int, Room> possibleRooms = new SortedDictionary <int, Room>(); //rooms not booked int maxCapacity = 0; foreach (KeyValuePair <string, Room> room in location.Rooms) { //checks if the room is available for that day if (!room.Value.BookedDays.Contains(finalDateLocation)) { possibleRooms.Add(room.Value.Capacity, room.Value); if (maxCapacity < room.Value.Capacity) { maxCapacity = room.Value.Capacity; // room with the biggest capacity } } } Room finalRoom = new Room(); //if there's no room for everybody the final room is the one with the biggest capacity if (maxCapacity < finalDateLocation.Invitees && possibleRooms.Count != 0) { finalRoom = possibleRooms[maxCapacity]; } //else choose the the first room that fits everyone else { foreach (KeyValuePair <int, Room> room in possibleRooms) { if (room.Key >= finalDateLocation.Invitees) { finalRoom = room.Value; break; } } } if (possibleRooms.Count > 0) { //changes the room availability to booked if it doesn't get cancelled _locations[finalDateLocation.LocationName].Rooms[finalRoom.Name].AddBookedDay(finalDateLocation); BroadcastUpdateLocation(location); return(finalRoom); } return(null); }
public void DONTwriteBroadcast(MeetingProposal meeting, List <ServerInfo> servers) { List <ServerInfo> newServerList = new List <ServerInfo>(servers); foreach (ServerInfo serverInfo in servers) { newServerList.RemoveAt(0); DONTwriteMeetingDelegate writeDel = new DONTwriteMeetingDelegate(this.DONTwriteMeeting); writeDel.BeginInvoke(serverInfo, meeting, servers, null, null); } }
public static void InformAllClientsOfMeetingState(MeetingProposal mp) { foreach (var c in clients) { if (mp.Invitees.Count == 0 || mp.CoordinatorUsername == c.Username || mp.Invitees.Contains(c.Username)) { c.ClientChannel.InformStateMeeting(mp, mp.Status); } } }
public void SendInvitations(List <string> invitees, MeetingProposal proposal) { // assumes every client knows every other client int threshold = (int)Math.Log(_knownClientUrls.Count, 2); if (threshold == 0) { threshold = 1; } // so that client does not block if a client he's trying to contact is not active Task task = Task.Run(() => { // easy case: there are few invitees so we can // send the invitations directly if (invitees.Count <= threshold) { foreach (string invitee in invitees) { // no need to send inviteesLeft because the invitation // is not going to need to be propapagated anymore _clients[invitee].ReceiveInvitation(proposal, _knownClientUrls.Count); } } // case with lots of invitees: send first directly and then // those to deliver the rest of the messages else { List <string> inviteesLeft = new List <string>( invitees.GetRange(threshold, invitees.Count - threshold)); // calculates how many clients must each client spread forward int nInviteesForEach = (inviteesLeft.Count) / threshold; int remainder = inviteesLeft.Count % threshold; int i = 0; foreach (string invitee in invitees.GetRange(0, threshold)) { if (i == 0) { _clients[invitee].ReceiveInvitation(proposal, _knownClientUrls.Count, inviteesLeft.GetRange(0, nInviteesForEach + remainder)); } else { _clients[invitee].ReceiveInvitation(proposal, _knownClientUrls.Count, inviteesLeft.GetRange(nInviteesForEach * i + remainder, nInviteesForEach)); } i++; } } }); }
public static void InformAllClientsOfJoinedMeeting(MeetingProposal mp, string username) { foreach (var c in clients) { if (mp.Invitees.Count == 0 || mp.CoordinatorUsername == c.Username || mp.Invitees.Contains(c.Username)) { c.ClientChannel.InformClientJoinedMeeting(mp, username); } } }
public static void InformClientsOfNewMeeting(MeetingProposal mp) { foreach (var c in clients) { if (mp.Invitees.Count == 0 || mp.CoordinatorUsername == c.Username || mp.Invitees.Contains(c.Username)) { c.ClientChannel.InformNewMeeting(mp); } } }
//IServer.createMeeting public void createMeeting(MeetingProposal meeting) { //REMINDER coordinator is in the meeting class //check if server is frozen if (this.freeze == true) { Action action = new Action(() => this.createMeeting(meeting)); actionList.Add(action); return; } this.randomSleep(); //see if locations are valid foreach (Slot slot in meeting.slotList) { if (!locationList.ContainsKey(slot.location)) { throw new MeetingException("location " + slot.location + " does not exist"); } } //if clientList is empty, send to all clients List <ClientInfo> senders = new List <ClientInfo>(); //remove coordinator //TODO lock? Dictionary <string, ClientInfo> newdic = new Dictionary <string, ClientInfo>(clientList); newdic.Remove(meeting.coordinator); if (meeting.invitees.Count == 0) { senders = new List <ClientInfo>(newdic.Values); } else { foreach (String invitee in meeting.invitees) { //only send meeting if the server knows the invitee if (newdic.ContainsKey(invitee)) { senders.Add(newdic[invitee]); } } } //Async send meeting to other servers updateView(); writeBroadcast(meeting, new List <ServerInfo>(serverList.Values)); //Async send meeting info to clients updateClients(meeting); }
public void RemoveMeetingFromList(MeetingProposal mp) { this.BeginInvoke(new MethodInvoker(delegate { foreach (ListViewItem item in listMeetingsLv.Items) { if (item.Text.Contains(mp.Topic)) { listMeetingsLv.Items.Remove(item); } } })); }
public static void InformAllServersOfMeetingState(MeetingProposal mp) { foreach (var s in otherServers) { try { s.ServerChannel.InformStateMeeting(mp); } catch (System.Net.Sockets.SocketException) { Console.WriteLine("Server: " + s.ServerID + " is down!"); } } }
public void updateClientAsync(ClientInfo clientInfo, MeetingProposal meeting) { //send async to only one IClient client = (IClient)Activator.GetObject( typeof(IClient), clientInfo.client_url); try{ client.sendMeeting(meeting); }catch (Exception ex) { Log.Error(ex, "cannot send meeting to client"); } }
//Creates a new meeting public MeetingProposal create(string[] args) { string meeting_topic = args[1]; int min_attendees = Int32.Parse(args[2]); int number_of_slots = Int32.Parse(args[3]); int number_of_invitees = Int32.Parse(args[4]); List <Slot> slotList = new List <Slot>(); List <string> invitees = new List <string>(); //Parse to get all slots and invitees int n = 5; for (int i = 0; i < number_of_slots; i++) { string[] split = args[n].Split(','); slotList.Add(new Slot(split[0], split[1])); n++; } for (int i = 0; i < number_of_invitees; i++) { invitees.Add(args[n]); n++; } //create meeting MeetingProposal meeting = new MeetingProposal(this.username, meeting_topic, min_attendees, slotList, invitees); //get server IServer server = (IServer)Activator.GetObject( typeof(IServer), server_url); //try to create meeting try{ server.createMeeting(meeting); } catch (MeetingException ex) { Log.Error(ex, "cannot create meeting"); //throw new ClientException("cannot create meeting", ex); return(null); }catch (Exception ex) { Log.Error(ex, "connection with server failed"); Action action = new Action(() => create(args)); getNewServer(action); return(null); //TODO call self method, make getNewServer only get server, //and dont rerun the method } meetingList.Add(meeting.topic, meeting); return(meeting); }
public void InformClientJoinedMeeting(MeetingProposal mp, string username) { //TODO take out of joined combo box if (Client.mainForm.listMeetingPage != null) { Client.mainForm.listMeetingPage.RemoveMeetingFromList(mp); Client.mainForm.listMeetingPage.AddMeetingToList(mp); if (Client.Username == username) { Client.mainForm.joinMeetingPage.RemoveMeetingFromCB(mp); } } }