def ConnectRequest(self, Thread, context): """ Send the connection info of a server to the client that contains the thread """ print('Client request') connection = self.get_thread_connection(Thread.uuid.hex) if connection: return connection else: with self.create_connection_lock: # Get the loads with self.messages_lock: for _, q in self.message_queues.items(): q.put( load_balancer_pb2.Request( type=load_balancer_pb2.RequestType.LOAD, thread=chat_pb2.Thread())) time.sleep(0.5) # Create thread on connection with lowest load channel = self.get_lowest_load() self.message_queues[channel].put( load_balancer_pb2.Request( type=load_balancer_pb2.RequestType.CREATETHREAD, thread=Thread)) # Add thread - channel mapping self.threads[Thread.uuid.hex] = channel self.loads = {} return self.connections[channel]
def handle_pongs(self): # Check which servers did not send pings missing_channels = list(set(self.connections.keys()) - set(self.pongs)) self.pongs = [] for channel in missing_channels: self.message_queues[channel].put( load_balancer_pb2.Request( type=load_balancer_pb2.RequestType.PING, thread=chat_pb2.Thread())) time.sleep(0.5) down_channels = list(set(missing_channels) - set(self.pongs)) for down_channel in down_channels: self.handle_server_down(down_channel)
def _pinger(self): """ Ping all knows servers every two seconds """ while True: self.pongs = [] with self.messages_lock: for _, q in self.message_queues.items(): q.put( load_balancer_pb2.Request( type=load_balancer_pb2.RequestType.PING, thread=chat_pb2.Thread())) # Wait half a second to receive all answers time.sleep(0.5) self.handle_pongs() time.sleep(2)
def __init__(self, username, ip, port): self.username = username load_balancer_channel = grpc.insecure_channel(ip + ':' + str(port)) self.load_balancer_connection = load_balancer_pb2_grpc.LoadBalancerServerStub( load_balancer_channel) # Key: Channel # Value: Connection to that channel self.connections = {} self.connections_lock = threading.RLock() # Key: Channel # Value: List of thread uuid hex that belong to that server connection self.connection_threads = {} self.connection_threads_lock = threading.RLock() # Key: Channel # Value: Message queue self.message_queues = {} self.message_queues_lock = threading.RLock() self.default_thread = chat_pb2.Thread(uuid=chat_pb2.UUID(hex=uuid.UUID( int=0).hex)) self.current_thread = None self.global_uuid = None self.max_reconnection_tries = 1 with open('client_log.csv', 'w', newline='') as file: logger = csv.writer(file) # action: 0 = message sent, 1 = message received, 2 = session expired logger.writerow(['timestamp', 'session_id', 'action']) # Key: session uuid hex # Value: dict(session, messages_sent, messages_received, updates_received, expiration_timer) self.sessions_lock = threading.RLock() self.sessions = {}
def handle_input(self, user_input): # Get thread msg = user_input in_split = user_input.split(' ') channel = None if len(in_split) > 1 and in_split[-2] == '|': self.current_thread = in_split[-1] if self.current_thread == 'global': self.current_thread = self.global_uuid msg = ' '.join(in_split[:-2]) # Listen to new thread if no session has been created if not self.thread_to_session(self.current_thread): uuid = chat_pb2.UUID(hex=str(self.current_thread)) thread = chat_pb2.Thread(uuid=uuid) channel = self.get_connection(thread) self.create_connection_or_add_thread(channel, thread) self.connect(thread) # Create message and put it in the right queue self.create_message(msg, channel)