Beispiel #1
0
    def solve_all(self, data):
        """
        This method expects data to be an object of the form {"id": pirate_id, "data": [{"id": clue_id, "data": clue_data}]}
        """
        logger.info("Solving all the clues")
        pirate_id = data["id"]
        logger.debug("pirate_id: %s", pirate_id)
        clue_list = data["data"]
        logger.debug("num clues: %s", len(clue_list))
        results = list(self.solve(clue) for clue in clue_list)

        summary = {"id": pirate_id, "data": results}
        pirates = discover('Pirate')
        first_mate = None
        for pirate in pirates:
            if pirate != (self.exposed_host(), self.exposed_port()):
                c = rpyc.connect(pirate[0], pirate[1])
                is_first_mate = c.root.is_leader
                answer = is_first_mate()
                if answer:
                    first_mate = pirate
                    break
        while not first_mate:
            logger.warn("No leader found, time to get a new one (%s)",
                        self.exposed_get_id())
            self.exposed_elect_leader()
            first_mate = leader
        c = rpyc.connect(first_mate[0], first_mate[1])
        verify_clues = rpyc. async (c.root.verify)
        result = verify_clues(summary)
        result.wait()
Beispiel #2
0
 def distribute_work(self, pirate_data):
     """
     This method expects pirate_data to be of the form [{"id": pirate_id, "data": [{"id": clue_id, "data": clue_data}]}].
     """
     logger.info('Starting work distribution')
     logger.info("Number of pirates: %s", len(pirate_data))
     all_clues = []
     for pirate in pirate_data:
         logger.debug("Adding %s to global clue list", len(pirate["data"]))
         all_clues.extend(pirate["data"])
     logger.info("Number of clues to be distributed: %s", len(all_clues))
     pirates = discover("pirate")
     logger.info("Found pirates: %s", pirates)
     logger.info("Splitting the clues into %s chunks", len(pirates) - 1)
     chunks = list(
         [all_clues[i::len(pirates) - 1] for i in range(len(pirates) - 1)])
     logger.info("Split into %s chunks", len(chunks))
     for chunk in chunks:
         logger.debug("Chunk length: %s", len(chunk))
     logger.debug('All pirates: %s', pirates)
     logger.debug('Leader: %s', leader)
     logger.debug('My host and port: %s',
                  (self.exposed_host(), self.exposed_port()))
     for pirate in pirates:
         if pirate != (self.exposed_host(), self.exposed_port()):
             logger.info("Sending clues to pirate at %s", pirate)
             c = rpyc.connect(pirate[0], pirate[1])
             give_clues = rpyc. async (c.root.set_clues)
             clues = chunks.pop()
             result = give_clues(clues)
             result.wait()
Beispiel #3
0
 def exposed_elect_leader(self):
     global leader
     logger.info('Electing a new leader')
     pirates = discover('Pirate')
     logger.info('Pirates available: %s', pirates)
     pirates = sorted(pirates)
     logger.debug('Sorted pirates: %s', pirates)
     leader = (pirates[0][0], pirates[0][1])
     logger.info('Found a new leader: %s', leader)
     for pirate in pirates:
         if (self.exposed_host(), self.exposed_port()) != pirate:
             c = rpyc.connect(pirate[0], pirate[1])
             set_leader = c.root.set_leader
             set_leader(leader)
     return leader
 def cluster_connect(self, max_connections=1):
     if len(self.service.connections) >= max_connections:
         self.logger.debug("Max connections reached ({})! ".format(
             len(self.service.connections)))
         return True  # We are connected with max connections
     try:
         con_tuples = discover(self.name)
     except rpyc.utils.factory.DiscoveryError as de:
         self.logger.warning(de)
         return False
     self.logger.debug("Discovered {} {}s".format(len(con_tuples),
                                                  self.name))
     for i in range(max_connections):
         con_tuple = con_tuples[i]
         # If the connection exists do not repeat it
         if self._already_connected(con_tuple):
             continue
         self.logger.debug("Connecting to {}:{}".format(*con_tuple))
         rpyc.connect(*con_tuple, service=self.service)
     return True
Beispiel #5
0
 def exposed_verify(self, data):
     """
     This method expects data to be of the form {"id": pirate_id, "data": [{"id": clue_id, "data": clue_data}]}
     """
     logger.info('Verifying with the captain...')
     request = qm.root.verify
     results = request(data)
     logger.info("%s: %s", results["status"], results["message"])
     try:
         finished = results["finished"]
     except Exception:
         finished = False
     if finished:
         logger.info(
             "Finally I'm done. Now to do Captain Rummy's dirty work so that we can split the treasure. Time to kill the crew."
         )
         pirates = discover('Pirate')
         for pirate in pirates:
             if pirate != (self.exposed_host(), self.exposed_port()):
                 c = rpyc.connect(pirate[0], pirate[1])
                 kill = rpyc. async (c.root.close_server)
                 kill()
         logger.info('And now that bastard of a quartermaster.')
         kill = rpyc. async (qm.root.close_server)
         kill()
         logger.info(
             "Wait, Captain Rummy, don't shoot! What about our pla--?")
         self.exposed_close_server()
     else:
         try:
             data = results["data"]
         except:
             logger.info("I'm done, I wonder what the others are up to...")
             data = []
         if data:
             logger.info("Not finished, redistributing failed clues")
             self.distribute_work(results["data"])
Beispiel #6
0
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s: (main) %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

DEV_MODE = False

if __name__ == '__main__':
    # Start the quartermaster service
    qm_servers = discover('QuarterMaster')
    qm = qm_servers[0]
    logger.info('Quartermaster running on {}:{}'.format(qm[0], qm[1]))
    # Connect to the qm service
    c = rpyc.connect(qm[0], qm[1], config={"logger": logger})
    # Set the netrefs
    wake = c.root.wake
    unlock = c.root.unlock
    gather = c.root.gather
    prepare = c.root.prepare
    add = c.root.add
    remove = c.root.remove
    ship_out = c.root.ship_out
    clues = c.root.clues
    verify = c.root.verify
    # Execute the correct netrefs and initialize all agents.
Beispiel #7
0
def main_exec(args):
    if args.mode == 'discover':
        try:
            conn_tuples = discover(args.name)
            for conn_tuple in conn_tuples:
                print("Connecting to {}".format(conn_tuple))
                conn = rpyc.connect(*conn_tuple)
                serv = conn.root
                print("~ Dumping:")
                pprint(serv.sync())
                conn.close()

        except rpyc.utils.factory.DiscoveryError as de:
            print(de)
        except AttributeError:
            conn.close()

    if args.mode == 'set':
        try:
            conn_tuples = discover(args.name)
            for conn_tuple in conn_tuples:
                print("Connecting to {}".format(conn_tuple))
                conn = rpyc.connect(*conn_tuple)
                serv = conn.root
                # Keep the types of the key and value from CLI
                key = eval(args.key)
                value = eval(args.value)
                print("~ '{}[{}] = {}'".format(args.name, key, value))
                serv.set(key, value)
                conn.close()
        except rpyc.utils.factory.DiscoveryError as de:
            print(de)

    if args.mode == 'get':
        try:
            conn_tuples = discover(args.name)
            for conn_tuple in conn_tuples:
                print("Connecting to {}".format(conn_tuple))
                conn = rpyc.connect(*conn_tuple)
                serv = conn.root
                # Keep the type of the key from CLI
                key = eval(args.key)
                print("~ '{}[{}]'".format(args.name, key))
                print(serv.get(key))
                conn.close()
        except rpyc.utils.factory.DiscoveryError as de:
            print(de)

    if args.mode == 'serve':
        if args.json_file:
            data = json.load(args.json_file)
        else:
            data = {}
        print('{}({})'.format(args.name, pformat(data)))
        try:
            cd = ClusterDict(store=data, name=args.name)
            if args.exit:
                cd.sync()
                cd.disconnect()
                sys.exit(0)

            import code
            code.interact(local=locals(),
                          banner="""
================================================
Variable 'cd' contains ClusterDict "{name}"
================================================
	""".format(name=args.name))
            # Reached here after killing Interactive console
            cd.service.close_down()
        except rpyc.utils.factory.DiscoveryError as de:
            print(de)
        except KeyboardInterrupt as ki:
            cd.service.close_down()
            print("Aborted by the user")
Beispiel #8
0
            try:
                data = results["data"]
            except:
                logger.info("I'm done, I wonder what the others are up to...")
                data = []
            if data:
                logger.info("Not finished, redistributing failed clues")
                self.distribute_work(results["data"])

    def exposed_close_server(self):
        logger.info('Shutting down...')
        server.close()


if __name__ == '__main__':
    # Get the local IP address of this pirate. The ThreadedServer#server attribute is not used, due to it always returning '0.0.0.0'.
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    myhost = s.getsockname()[0]
    s.close()
    leader = tuple()
    pirate_id = None
    qm_details = discover('QuarterMaster')
    if len(qm_details) != 1:
        raise Exception(
            'One and only one quartermaster should exist before trying to wake a pirate up'
        )
    qm = rpyc.connect(qm_details[0][0], qm_details[0][1])
    server = ThreadedServer(PirateService, auto_register=True, logger=logger)
    server.start()