class Simulator: def __init__(self, args): self.env = simpy.Environment() self.args = args self.client_params = {} self.server_params = {} self.misc_params = {} self.parse_file() self.check_settings() self.print_session_summary() self.requests = {} self.__parse_requests() self.client_params[Contract.C_CLIENT_COUNT] = len(self.requests) random.seed(args.seed) self.__clients = [] logpath = args.logpath if logpath[:-1] != '/': logpath += '/' self.servers_manager = ServerManager(self.env, self.server_params, self.client_params, self.misc_params, self.__clients, logpath) client_logger = Logger(self.env, logpath) parity_group_creator = ParityGroupCreator(self.client_params, self.server_params) for i in range(len(self.requests)): self.__clients.append( Client(self.env, i, client_logger, self.servers_manager, self.client_params, self.misc_params, parity_group_creator)) self.servers_manager.add_requests_to_clients(self.requests) def print_session_summary(self): print("Server Count: {}".format( self.server_params[Contract.S_SERVER_COUNT])) print( "Devices per server: {} ({} MBps Reading, {} MBps Writing)".format( self.server_params[Contract.S_HDD_DATA_COUNT], self.server_params[Contract.S_HDD_DATA_READ_MBPS], self.server_params[Contract.S_HDD_DATA_WRITE_MBPS])) print("Geometry {}+{}".format( self.client_params[Contract.C_GEOMETRY_BASE], self.client_params[Contract.C_GEOMETRY_PLUS])) print("Request file: {}".format(self.args.request)) print() def check_settings(self): # geometry must be less or equal than server number assert (self.client_params[Contract.C_GEOMETRY_BASE] + self.client_params[Contract.C_GEOMETRY_PLUS]) \ <= self.server_params[Contract.S_SERVER_COUNT] def parse_file(self): configuration = open(self.args.config, "r") for line in configuration: couple = line.strip().split('=') try: field = couple[0].strip() value = couple[1].strip() if field[0] == "C": # Client options self.client_params[field] = int(value) elif field[0] == "S": # Server options self.server_params[field] = int(value) elif field[0] == "M": # Misc Options self.misc_params[field] = value # self.params[couple[0].strip()] = int(couple[1].strip()) except Exception: if line[0] == '#': continue def __from_human(self, human_number: str): """ Replace human readable format with machine readable numbers. Used to improve request file readability :param human_number: the string representing the number :return: the integer represented """ r = human_number.replace("P", "GG").replace("T", "GM").replace( "G", "MM").replace("M", "000") return int(r) def __parse_requests(self): requests = open(self.args.request, 'r') # parses the file once to create an empty container of requests clients_count = 0 for line in requests: try: if line == "" or line.startswith('#'): continue if line.strip()[0] != '*': clients_count += 1 except Exception: pass for i in range(clients_count): self.requests[i] = [] requests.seek(0) line_number = 0 for line in requests: line = line.strip() try: if line == "" or line.startswith('#'): continue words = line.split(" ") if words[0] == '*': req = (self.__from_human(words[1]), self.__from_human(words[2])) if req[0] != 0 and req[1] != 0: for i in range(clients_count): self.requests[i].append(req) else: req = (self.__from_human(words[0]), self.__from_human(words[1])) if req[0] != 0 and req[1] != 0: self.requests[line_number].append(req) line_number += 1 except Exception: if line[0] == '#': continue def print_params(self, verbose=False): if args.verbose or verbose: for key, value in self.client_params.items(): print('{:>30} : {:d}'.format(key, value)) print() print("- - - - - - - - - - - - - - - - - - - -") print() for key, value in self.server_params.items(): print('{:>30} : {:d}'.format(key, value)) def run(self): self.env.run()