def handle_select(rlist, xlist): if xlist: raise ZeroMQException("Unknown error occurred during a select() call") if self.reset_socket in rlist: self.reset_socket.recv() self.reset() return True if self.sub_socket in rlist: local_distance_matrix = self.recv_distance_matrix() if config.is_debug(): log.info("received distance matrix: %s", local_distance_matrix) log.info("step ...") singletons.simulation_manager.step(1, distance_matrix=local_distance_matrix) self.send_sync() # wait for sync reply or error rlist, _, xlist = zmq.select([self.reset_socket, self.svc], [], []) # rlist, _, xlist = zmq.select([self.svc], [], []) if handle_select(rlist, xlist): return True # self.sync() if config.is_debug(): log.debug("stepped ...") if self.svc in rlist: self.recv_sync() return True
def get_node_logger(node_id, log_level=None): """ Get a colored logger for a node with id `node_id`. A file handler will be created which logs to the standard log directory. """ from colorlog import ColoredFormatter if log_level is None: log_level = get_log_level() format_str = "%(message)s" if not config.is_debug() else formatter_str_time formatter = ColoredFormatter( "%(blue)s{}>>>%(reset)s %(log_color)s {fmt_str}".format(node_id, fmt_str=format_str), datefmt=None, reset=True, log_colors={ 'DEBUG': 'cyan', 'INFO': 'green', 'WARNING': 'yellow', 'ERROR': 'red', 'CRITICAL': 'red', } ) logger = get_logger(node_id, formatter, log_level=log_level) logger.addHandler(get_file_handler("node_%s.txt" % node_id)) return logger
def start(self, tunnel_ip): """ This method contains steps 1-3. Parameters ---------- tunnel_ip : str Returns ------- scenario_config : str The scenario config as json. """ self.tunnel_ip = tunnel_ip ######################################################### # State: Register ######################################################### self.myprint("registering at server ...") self.send_no_server_id(States.STATE_REGISTER) if config.is_debug(): self.myprint("registering at server [done]") server_id = self.recv() self.server_id = server_id self.myprint("server id is: %d" % int(server_id)) # TODO: RENAME state! ######################################################### # State: Information exchange ######################################################### server_score = ServerScore.factory()() self.send_server_id(States.STATE_EXCHANGE, tunnel_ip, server_score.get_score()) scenario_config = json.dumps(self.recv()) self.myprint("scenario config: %s" % pformat(scenario_config)) ######################################################### # State: Start Nodes ######################################################### self.myprint("starting nodes") self.start_nodes(scenario_config) self.send_server_id(States.STATE_START_NODES) self.myprint("syncing with other nodes ...") self.recv() self.myprint("synced with other nodes ...") return scenario_config
def enter_run_loop(self): while True: self.send_server_id(States.STATE_DISTANCE_MATRIX) distance_matrix = self.recv_distance_matrix() # did not receive individual matrix if not config.is_publish_individual_distance_matrices(): distance_matrix = singletons.simulation_manager.get_local_distance_matrix_to_servers(distance_matrix) if config.is_debug(): self.myprint("distance matrix: %s" % distance_matrix) singletons.simulation_manager.step(1, distance_matrix=distance_matrix)
def sync_subscribers(self): """ Sync the subscribers and provide some debugging information about the sync progress (if debug mode) """ log.info("syncing subscribers ...") def fun(expecter, idx, cnt): log.debug("%d/%d clients synced ...", idx, cnt) # add some debug info after_response_fun = fun if config.is_debug() else lambda x, y, z: None expect_distance_matrix = self.get_expecter_state(States.STATE_DISTANCE_MATRIX, 1, after_response_fun) # sync clients and send each his distance matrix ResponderArgument(self.router_socket, self.protocol, expect_distance_matrix, '')() log.info("syncing subscribers [done]")
def recv_distance_matrix(self): """ Receive the whole distance matrix via the publish-subscribe socket and filter out the relevant part. Returns ------- DistanceMatrix """ whole_distance_matrix = DistanceMatrix.detransform_distance_matrix(self.deserialize(self.sub_socket.recv())) if config.is_debug(): log.info("server id: %d", scenario_config.get_distributed_server_id()) local_distance_matrix = singletons.simulation_manager.get_local_distance_matrix_to_servers( whole_distance_matrix) return DistanceMatrix.factory()(local_distance_matrix)
def __init__( self, replable, timeout, flo, brief_logger=None, interactive_result_stdout_writing=True, verbose_logger=None, shell_prompt=scenario_config.get_shell_prompt(), logger_echo_commands=False, template_engine_kwargs=None, return_value_checker=None, enter_shell_send_newline=True, ): """ Parameters ---------- replable : REPLable The repl reference. timeout : float Timeout flo: file-like-object Read the string contents from `flo`. brief_logger : logigng.logger Logs briefly all commands (log level: info). Also used for exception and error logging! interactive_result_stdout_writing: bool, optional (default is False) Redirect command stdout/stderr to local stdout. verbose_logger : logging.Logger, optional (default is None) Log complete output! Very verbose. Log output if logger given. Only if debug mode is on! Note: exceptions are only logged with a Logger! shell_prompt : str, optional (default is the value from the current scenario config) The shell prompt to expect (regular expression, needed to wait for the completion of a command). The re engine uses the flags: re.DOTALL | re.MULTILINE. logger_echo_commands : bool, optional (default is False) If enabled, all executed commands are written to the log file too. The shell e.g. echos automatically back, so it is not needed. template_engine_kwargs : dict, optional (default is {}) Use to pass through keyword arguments to the template engine. return_value_checker : fun: str -> str -> object, optional, (default is None) If supplied, apply the function on output of the REPL after the REPL returned. First argument is the command which gets executed, second the result of the execution. Raises :py:class:`.REPLUnexpectedResult` if this method raises an exception. # TODO: DOC enter_shell_send_newline """ if template_engine_kwargs is None: template_engine_kwargs = {} self.replable = replable self.flo = flo self.interactive_result_stdout_writing = interactive_result_stdout_writing self.brief_logger = brief_logger self.verbose_logger = verbose_logger if config.is_debug() else None self.shell_prompt = shell_prompt self.log_file_echo_command = logger_echo_commands self.template_engine_kwargs = template_engine_kwargs self.return_value_checker = return_value_checker self.timeout = timeout self.enter_shell_send_newline = enter_shell_send_newline if self.brief_logger is None: raise ValueError("A valid logger must be given!") self.sock = None self.re_shell_prompt = re.compile(shell_prompt, flags=re.DOTALL | re.MULTILINE)
def recv_sync(self): if config.is_debug(): log.debug("syncing with server [done]") self.recv()