def process_leader_message(leader_json): if leader_json == app.id: app_logger.debug(debug_stamp() + 'Leader information distributed successfully') backip, backport = decode_id(app.nodes[C.NODE_BACK]) elif app.nodes[C.NODE_FRONT]: dstip, dstport = decode_id(app.nodes[C.NODE_FRONT]) app.conn.send_leader(dstip, dstport, leader_json) app.nodes[C.NODE_LEADER] = leader_json app_logger.info(info_stamp() + 'New leader: %s', app.nodes[C.NODE_LEADER])
def logout(): if app.nodes[C.NODE_FRONT] != app.nodes[C.NODE_BACK]: backip, backport = decode_id(app.nodes[C.NODE_BACK]) frontip, frontport = decode_id(app.nodes[C.NODE_FRONT]) app.conn.send_front_setting(backip, backport, app.nodes[C.NODE_FRONT]) app.conn.send_back_setting(frontip, frontport, app.nodes[C.NODE_BACK]) if app.status == C.STATUS_LEADER: app.conn.broadcast_loggedout_node(app.id, app.topology) app_logger.info(info_stamp() + "Logging out...") report_logout(app.id) os._exit(0)
def process_new_connection(request): headers = request.headers newip = headers[C.HEADER_IP] newport = headers[C.HEADER_PORT] new_node = encode_id(newip, newport) app_logger.debug(debug_stamp() + "Welcoming %s", new_node) if not app.nodes[C.NODE_FRONT]: app.nodes[C.NODE_FRONT] = new_node old_back_friend = app.nodes[C.NODE_BACK] app.nodes[C.NODE_BACK] = new_node welcome_dict = {C.NODE_LEADER: app.nodes[C.NODE_LEADER]} if app.nodes[C.NODE_FRONT] == app.nodes[C.NODE_BACK]: welcome_dict[C.NODE_BACK] = app.id else: welcome_dict[C.NODE_BACK] = old_back_friend try: old_back_ip, old_back_port = decode_id(old_back_friend) app.conn.send_front_setting(old_back_ip, old_back_port, app.nodes[C.NODE_BACK]) except: pass try: report_new_node(new_node) except: pass return json.dumps(welcome_dict), C.CODE_OK
def process_candidate_json(candidate_json): candidate_value = calc_value(candidate_json) if app.status != C.STATUS_LEADER: try: dstip, dstport = decode_id(app.nodes[C.NODE_FRONT]) if int(candidate_value) > int(app.value): app_logger.debug(debug_stamp() + 'Resending candidate: %s', candidate_json) app.conn.send_candidate(dstip, dstport, candidate_json) elif int(app.value) > int(candidate_value) and app.nodes[ C.NODE_LEADER]: app_logger.debug( debug_stamp() + 'Swapping me as a candidate: %s', candidate_json) start_candidacy() elif int(app.value) == int(candidate_value): app_logger.debug(debug_stamp() + 'Setting the leader state') app.status = C.STATUS_LEADER app.nodes[C.NODE_LEADER] = app.id app.conn.send_leader(dstip, dstport, app.id) except: pass
def runner(ipport, friend, debug): if debug: ch.setLevel(logging.DEBUG) ip, port = decode_id(ipport) friend_ip, friend_port = decode_id(friend) # main thread for request handlers and processing m = threading.Thread(name='main_handler', target=main_handler, args=(ip, port)) m.setDaemon(True) # daemon thread for leader checking i = threading.Thread(name='raw_input', target=input) i.setDaemon(True) # daemon thread for connection checking c = threading.Thread(name='connection', target=connection, args=(friend_ip, friend_port)) c.setDaemon(True) # daemon thread for leader checking s = threading.Thread(name='leader_checker', target=leader_checker) s.setDaemon(True) # daemon thread for heartbeat to leader h = threading.Thread(name='heartbeat', target=heartbeat) h.setDaemon(True) # daemon thread for front friend checking f = threading.Thread(name='frontbeat', target=frontbeat) f.setDaemon(True) m.start() i.start() c.start() s.start() h.start() f.start() while True: sleep(1)
def report_new_node(new_node): try: if app.status == C.STATUS_LEADER: app_logger.info(info_stamp() + "%s joined", new_node) app.conn.broadcast_new_node(new_node, app.topology) else: leaderip, leaderport = decode_id(app.nodes[C.NODE_LEADER]) app.conn.new_node_report(leaderip, leaderport, new_node) except: pass
def broadcast_dead_node(self, dead_node, topology): headers = self.build_header(CONST.TYPE_INFO_DEATH, self.ip, self.port) dead_data = self.build_node_json(dead_node) for node in topology: try: dstip, dstport = decode_id(node) url = self.build_url(dstip, dstport) result = requests.post(url, headers=headers, json=dead_data) except: pass
def broadcast(self, message, topology): headers = self.build_header(CONST.TYPE_MESSAGE, self.ip, self.port) message_data = self.build_message_from_dict(message) for node in topology: try: dstip, dstport = decode_id(node) url = self.build_url(dstip, dstport) result = requests.post(url, headers=headers, json=message_data) except: pass
def friendhit(): frontip, frontport = decode_id(app.nodes[C.NODE_FRONT]) try: backup_front = app.conn.friendbeat(frontip, frontport) app.repeater = 0 if backup_front == app.id: app.nodes[C.NODE_BACKUP_FRONT] = None else: app.nodes[C.NODE_BACKUP_FRONT] = backup_front except Exception as e: friendhit_repeating(app.nodes[C.NODE_FRONT])
def report_dead_node(dead_node): try: leaderip, leaderport = decode_id(app.nodes[C.NODE_LEADER]) if app.status == C.STATUS_LEADER: app_logger.info(info_stamp() + "%s lost connection", dead_node) app.conn.broadcast_dead_node(dead_node, app.topology) remove_node(dead_node) else: app.conn.death_report(leaderip, leaderport, dead_node) except: pass
def heartbeat(): while True: try: leader_ip, leaderport = decode_id(app.nodes[C.NODE_LEADER]) if app.status != C.STATUS_LEADER: app.conn.heartbeat(leader_ip, leaderport) except: if app.nodes[C.NODE_LEADER]: app_logger.info(info_stamp() + "%s lost connection", app.nodes[C.NODE_LEADER]) app.nodes[C.NODE_LEADER] = None finally: time.sleep(C.SLEEP_TIME)
def friendhit_repeating(front_node): app.repeater += 1 if app.repeater >= 3: app_logger.debug(debug_stamp() + "Lost direct connection to %s", app.nodes[C.NODE_FRONT]) app.nodes[C.NODE_FRONT] = app.nodes[C.NODE_BACKUP_FRONT] if app.nodes[C.NODE_FRONT]: newfrontip, newfrontport = decode_id(app.nodes[C.NODE_FRONT]) try: app.conn.send_back_setting(newfrontip, newfrontport, app.id) except: pass if app.nodes[C.NODE_BACK] == front_node: app.nodes[C.NODE_BACK] = None app.repeater = 0 report_dead_node(front_node) else: app_logger.debug( debug_stamp() + 'Trying to establish connection... (%s)', str(app.repeater)) time.sleep(1) friendhit()
def input(): while True: input_string = raw_input() if input_string == '--i' or input_string == '--info': print_info() elif input_string == '--l' or input_string == '--logout': logout() elif input_string == '--d' or input_string == '--debug': ch.setLevel( logging.DEBUG) if ch.level == logging.INFO else ch.setLevel( logging.DEBUG) else: try: if app.status == C.STATUS_LEADER: send_regular_message_from_leader(input_string) else: dstip, dstport = decode_id(app.nodes[C.NODE_LEADER]) app.conn.send_message(dstip, dstport, input_string, 0) app_logger.debug(debug_stamp() + 'Sending message: %s', input_string) except: app_logger.debug(debug_stamp() + 'Message has not been sent.') pass
def report_logout(loggedout_node): try: leaderip, leaderport = decode_id(app.nodes[C.NODE_LEADER]) app.conn.logout_report(leaderip, leaderport, loggedout_node) except: app_logger.debug(debug_stamp() + 'Logging off without reporting')
def start_candidacy(): try: dstip, dstport = decode_id(app.nodes[C.NODE_FRONT]) app.conn.send_candidate(dstip, dstport, app.id) except: pass