def init_topichash(topic): queue_path = '/owner_queue/' queue_node = '/owner_queue/{}'.format(topic) topic_path = "/topics/" topic_node = "/topics/{}".format(topic) strength = bytes("{}".format("1").encode("utf-8")) if zookeeper.exists(topic_node) and zookeeper.exists('/owner_queue/'): pass else: zookeeper.ensure_path(topic_path) zookeeper.create(topic_node, strength) zookeeper.ensure_path(queue_path) zk_queue = Queue(zookeeper, queue_node) node = bytes(topic_node.encode("utf-8")) zk_queue.put(node, 1)
def set_topic(topic): topic_node = "/topics/{}".format(topic) queue_node = '/owner_queue/{}'.format(topic) strength = None if not get_topic(topic): init_topichash(topic) strength = get_topic(topic)[1] else: cur_strength = get_topic(topic)[1] cur_strength += 1 strength = bytes("{}".format(str(cur_strength)).encode("utf-8")) zookeeper.set(topic_node, strength) zk_queue = Queue(zookeeper, queue_node) priority = zk_queue.__len__() node = bytes(topic_node.encode("utf-8")) zk_queue.put(node, priority + 1) print("Strength adjusted for set: {}".format(strength)) return (topic, strength)
class Player: name = '' def __init__(self, ip_port, name): '''Initialize everyting for the player''' self.name = name logging.basicConfig() try: # Create client self.zk = KazooClient(hosts=ip_port, logger=logging) self.zk.start() except Exception as ex: print( 'Error connecting the Zookeeper Service, Please make sure the service is up or the IP:PORT provided is correct' ) sys.exit(-1) # Ensure Paths self.zk.ensure_path('/csjain_queue') self.zk.ensure_path('/csjain_players') # Create Data structures self.my_queue = Queue(self.zk, '/csjain_queue') self.party = Party(self.zk, '/csjain_players', self.name) def join_party(self): '''Add player to list of current online players''' self.party.join() def leave_party(self): '''Remove player from list of current online players''' self.party.leave() def post_score(self, score): '''Post a random score''' if self.name not in set(self.party): self.party.join() self.my_queue.put('{}:{}'.format(self.name, str(score)).encode('utf-8'))
class ScoreWatcher: curr_score = [] high_score = [] online_players = set() def __init__(self, ip_port, score_board_size): '''Initialize everyting for the watcher''' logging.basicConfig() self.score_board_size = score_board_size self.is_dump = False self.is_init_client = True try: # Create client self.zk = KazooClient(hosts=ip_port, logger=logging) self.zk.start() except Exception as ex: print( 'Error connecting the Zookeeper Service, Please make sure the service is up or the IP:PORT provided is correct' ) sys.exit(-1) # Ensure Paths self.zk.ensure_path('/csjain_queue') self.zk.ensure_path('/csjain_players') # Create Data structures self.score_queue = Queue(self.zk, '/csjain_queue') self.party = Party(self.zk, '/csjain_players') self.online_players = set(self.party) if len(self.score_queue) == 0: print('Most recent scores') print('------------------') print('\n') print('Highest scores') print('--------------') # Create Watchers _ = ChildrenWatch(self.zk, '/csjain_queue', self.process_score) _ = ChildrenWatch(self.zk, '/csjain_players', self.process_client) def print_scoreboards(self): '''Print the formatted Recent Score and Leader Board''' if self.is_dump: return print('Most recent scores') print('------------------') if self.curr_score: for player, score in self.curr_score: if player in self.online_players: print('{}\t\t{}\t**'.format(player, score)) else: print('{}\t\t{}'.format(player, score)) print('\n') print('Highest scores') print('--------------') if self.high_score: for player, score in self.high_score: if player in self.online_players: print('{}\t\t{}\t**'.format(player, score)) else: print('{}\t\t{}'.format(player, score)) print('\n') def process_score(self, children): '''Process any pending score or new score that is posted''' if not children: return True while len(self.score_queue) > 0 and not self.is_dump: new_score = self.score_queue.get() if not new_score: break # Update high score self.high_score.append(new_score.split(':')) self.high_score = sorted(self.high_score, key=lambda x: float(x[1]), reverse=True) self.high_score = self.high_score[:min(len(self.high_score), self. score_board_size)] # Update current score if not self.curr_score: self.curr_score = [new_score.split(':')] elif len(self.curr_score) < self.score_board_size: self.curr_score = [new_score.split(':')] + self.curr_score else: self.curr_score = [new_score.split(':')] + self.curr_score[:-1] self.print_scoreboards() return True def process_client(self, children): '''Process updates to a player joining or leaving the game''' if self.is_init_client: self.is_init_client = False return True self.online_players = set(self.party) if self.curr_score: self.print_scoreboards() return True def dump_scoreboard(self): self.is_dump = True for name, score in self.high_score: self.score_queue.put('{}:{}'.format(name, score).encode('utf-8'))