diff --git a/roles/host.py b/roles/host.py index 7289673c3522b24102a6ca73082db400db572c05..32c6a041015bae39c98b6ed606fcde4d18e146c4 100644 --- a/roles/host.py +++ b/roles/host.py @@ -93,7 +93,11 @@ class Host(object): def store_solution(self, solution): if 'part_id' in solution: + request_id = solution['request_id'] + if solution['status'] != 'done': + if request_id in self.request: + self.request[request_id].store_failed(solution) return {'status': 'ignored'} problem_key = solution['problem'] @@ -102,14 +106,14 @@ class Host(object): self.request[request_id].store_response(solution) if problem_key in self.problems: - res = self.problems[problem_key].put_partial_solution(solution) + parts_valid = self.problems[problem_key].put_partial_solution(solution) else: - res = False + parts_valid = False print(solution['solution']) print(solution['line_map'], solution['block_map']) - if res: + if parts_valid and self.request[request_id].is_receive_completed: merge_problem = self.problems[problem_key].partial_merge_problem # print(merge_problem) merge_problem['request_id'] = solution['request_id'] @@ -207,6 +211,9 @@ class Host(object): return {} elif cmd == 'cancel': self.worker_manager.request_cancel(params) + _requests = self.problem_to_request[params['problem']] + for r in _requests: + self.request[r].cancel() return {'status': 'canceled'} elif cmd == 'worker/reset': self.worker_manager.reset_worker(params['address']) @@ -364,7 +371,6 @@ class Worker(object): class Request(object): def __init__(self, worker_manager, data, worker, timeout=10000, merge_solvers=list()): - # self.worker_manager = worker_manager self.data = data self.timeout = timeout @@ -382,9 +388,11 @@ class Request(object): if self.solver.partial_mode: self.part_nums = len(data['group_problems']) self.solved = [0 for v in range(self.part_nums + 1)] + # self.received = [0 for v in range(self.part_nums)] else: self.part_nums = 1 self.solved = [0] + # self.received = [] self.is_processed = False @@ -395,6 +403,14 @@ class Request(object): data['timeout'] = self.timeout data['merge_solvers'] = self.merge_solvers return data + + # @property + # def is_receive_completed(self): + # return all([v>0 for v in self.received]) + + @property + def is_receive_completed(self): + return all([v!=0 for v in self.solved[:-1]]) def get_id(self): return self.request_id @@ -407,10 +423,25 @@ class Request(object): if self.start_time is None: self.start_time = time.time() + def cancel(self): + if self.solved[-1] == 0: + self.solved[-1] = -1 + + def store_failed(self, data): + + self.response.append(data) + if 'part_id' in data: + idx = data['part_id'] + self.solved[idx] = -1 + if all([v!=0 for v in self.solved[:-1]]) and any([v<0 for v in self.solved[:-1]]): + self.solved[-1] = -1 + self.done_time = time.time() + else: + self.solved[-1] = -1 + self.done_time = time.time() + def store_response(self, data): - # worker = data['worker'] - # self.response[worker].append(data) - # self.response[worker] = data + self.response.append(data) print(data) if 'part_id' in data: @@ -420,8 +451,9 @@ class Request(object): self.solved[idx] = 1 else: self.solved[idx] = -1 - if all([v!=0 for v in self.solved]) and any([v<0 for v in self.solved]): + if all([v!=0 for v in self.solved[:-1]]) and any([v<0 for v in self.solved[:-1]]): self.solved[-1] = -1 + self.done_time = time.time() else: if data['status'] == 'done': self.solved[-1] = 1 @@ -443,10 +475,15 @@ class Request(object): elif self.solved[-1] == -1: if self.start_time is None: self.start_time = time.time() - elapsed_time = self.done_time - self.start_time - et_minutes = int(elapsed_time // 60) - et_seconds = int(elapsed_time % 60) - status = f'failed [{et_minutes}:{et_seconds:02}]' + counter = sum([v!=0 for v in self.solved]) + fail_counter = sum([v<0 for v in self.solved]) + if self.done_time is None: + status = f'canceled ({counter}/{len(self.solved)} done)' + else: + elapsed_time = self.done_time - self.start_time + et_minutes = int(elapsed_time // 60) + et_seconds = int(elapsed_time % 60) + status = f'failed ({counter}/{len(self.solved)} done) [{et_minutes}:{et_seconds:02}]' else: if self.solver.status == 'Not connected': status = 'Not connected' @@ -455,8 +492,12 @@ class Request(object): if len(self.solved) == 1: status_mes = 'Running' elif len(self.solved) > 1: - counter = sum([v>0 for v in self.solved]) - status_mes = f'{counter}/{len(self.solved)}' + counter = sum([v!=0 for v in self.solved]) + fail_counter = sum([v<0 for v in self.solved]) + if fail_counter > 0: + status_mes = f'{counter}/{len(self.solved)}' + else: + status_mes = f'{counter}/{len(self.solved)}' if self.start_time is None: self.start_time = time.time() diff --git a/utils/data.py b/utils/data.py index bc5ee62904f136cc54f67221361bf5a0e09fc0fc..f312ea875e5421bd768db081af61a7d83ba60df9 100644 --- a/utils/data.py +++ b/utils/data.py @@ -387,7 +387,6 @@ class Problem(object): with open(outpath, 'w') as fp: json.dump(self.get_dict(), fp, indent=4) - # print([len(v)>0 for v in self.partial_solutions]) if all([len(v)>0 for v in self.partial_solutions]): return True else: