diff --git a/roles/host.py b/roles/host.py index d0d18a68dff3e12c43cc141694a2ec4dd6778111..592eeaf9b8b2310a783a0c86d8fad5d00904664f 100644 --- a/roles/host.py +++ b/roles/host.py @@ -54,16 +54,24 @@ class Host(object): if problem is None: return {'status': 'key error'} else: - request = Request(self.worker_manager, problem.get_dict(), solvers=solvers) - request_id = request.get_id() - self.request[request_id] = request - self.problem_to_request[problem_key].append(request_id) + # request = Request(self.worker_manager, problem.get_dict(), solvers=solvers) + if solvers is None: + _solvers = self.worker_manager.get_workers() + else: + _solvers = dict() + for k, v in self.worker_manager.get_workers().items(): + if k in solvers: + _solvers[k] = v + for _, v in _solvers.items(): + request = Request(self.worker_manager, problem.get_dict(), v) + request.broadcast() + + request_id = request.get_id() + self.request[request_id] = request + self.problem_to_request[problem_key].append(request_id) - request.broadcast() return { 'status': 'processed', - 'request_id': request_id, - 'timeout': request.timeout } def get_problems(self): @@ -81,6 +89,10 @@ class Host(object): if solution['status'] != 'done': return {'status': 'ignored'} problem_key = solution['problem'] + + request_id = solution['request_id'] + if request_id in self.request: + self.request[request_id].store_response(solution) if problem_key in self.problems: res = self.problems[problem_key].put_partial_solution(solution) @@ -308,6 +320,11 @@ class Worker(object): self.name = params['name'] self.host = params['host'] self.role = params['role'] + + if not 'partial_mode' in params: + self.partial_mode = False + else: + self.partial_mode = params['partial_mode'] self.params = params self.status = 'Ready' @@ -339,23 +356,33 @@ class Worker(object): class Request(object): - def __init__(self, worker_manager, data, timeout=10000, solvers=None): - self.worker_manager = worker_manager + def __init__(self, worker_manager, data, worker, timeout=10000): + # self.worker_manager = worker_manager self.data = data self.timeout = timeout self.request_id = time.time() - self.broadcast_time = None + self.request_time = None + self.done_time = None - if solvers is None: - self.solvers = list(self.worker_manager.get_workers().keys()) - else: - self.solvers = solvers + # if solvers is None: + # self.solvers = list(self.worker_manager.get_workers().keys()) + # else: + # self.solvers = solvers + self.solver = worker self.response = dict() - for w in self.solvers: - self.response[w] = list() + # for w in self.solvers: + # self.response[w] = list() + self.response = list() + + if self.solver.partial_mode: + self.part_nums = len(data['group_problems']) + self.solved = [0 for v in range(self.part_nums + 1)] + else: + self.part_nums = 1 + self.solved = [0] @property def request_data(self): @@ -371,55 +398,62 @@ class Request(object): return self.request_data def store_response(self, data): - worker = data['worker'] - self.response[worker].append(data) + # worker = data['worker'] + # self.response[worker].append(data) # self.response[worker] = data + self.response.append(data) + print(data) + if 'part_id' in data: + idx = data['part_id'] + print(idx) + if data['status'] == 'done': + self.solved[idx] += 1 + else: + self.solved[-1] = 1 + self.done_time = time.time() def get_status(self): - worker_count = 0 - response_count = 0 - for v in self.solvers: - worker_count += 1 - if v in self.response: - response_count += 1 - + status = '' - if worker_count == response_count: - status = 'done' - # elif time.time() - self.broadcast_time > self.timeout: - # status = 'timeout' - else: - elapsed_time = time.time() - self.broadcast_time + + if self.solved[-1] == 1: + elapsed_time = self.done_time - self.request_time et_minutes = int(elapsed_time // 60) et_seconds = int(elapsed_time % 60) - # status = 'processing' - status = f'{et_minutes}:{et_seconds:02}' - - if self.broadcast_time is None: - progress = 0, + status = f'done ({self.solved[-1]}) [{et_minutes}:{et_seconds:02}]' + elif self.solved[-1] == -1: + status = 'failed' else: - progress_problem = response_count / worker_count * 100 - progress_time = (time.time() - self.broadcast_time) / self.timeout * 100 - progress = min(100, max(progress_problem, progress_time)) - - worker_status = dict() - for v in self.solvers: - if v in self.response and len(self.response[v]) > 0: - worker_status[v] = self.response[v][0]['status'] + if self.solver.status == 'Not connected': + status = 'Not connected' else: - if self.worker_manager.workers[v].status == 'Not connected': - worker_status[v] = 'Not connected' - else: - worker_status[v] = 'Waiting for response' + if len(self.solved) == 1: + status_mes = 'Waiting for response' + elif len(self.solved) > 1: + counter = sum([v>0 for v in self.solved]) + status_mes = f'{counter}/{len(self.solved)}' + + elapsed_time = time.time() - self.request_time + et_minutes = int(elapsed_time // 60) + et_seconds = int(elapsed_time % 60) + elapsed_time_str = f'{et_minutes}:{et_seconds:02}' + + status = f'{status_mes} [{elapsed_time_str}]' return { 'status': status, - 'workers': worker_count, - 'solutions': response_count, - 'progress': progress, - 'worker_status': worker_status + 'worker': self.solver.address, + # 'solutions': response_count, + # 'progress': progress, + # 'worker_status': worker_status } def broadcast(self): - self.worker_manager.broadcast('solve', self.request_data, solvers=self.solvers) - self.broadcast_time = time.time() + + def _sender(): + self.solver.post('solve', self.request_data) + + _th = threading.Thread(name=f'request_sender_{self.solver.address}', target=_sender, daemon=True) + _th.start() + + self.request_time = time.time() diff --git a/roles/solver.py b/roles/solver.py index 208523195217adf8e1ffc669587ab14536ab306b..963ae92eeabcaa4e9f12bdbfa0aceb519193e3d0 100644 --- a/roles/solver.py +++ b/roles/solver.py @@ -82,6 +82,9 @@ class Solver(object): solution['block_map'] = gblock_map self.submit_solution(data, solution) + + if self.solver.stop_flag: + break else: start_time = time.time() solution = self.solver.solve(params) diff --git a/static/js/adc2019.js b/static/js/adc2019.js index 5b83abfb3595b40cc72f58dce495863fef35737b..02082ed1634f2f622684873d858a38ed962dd98a 100644 --- a/static/js/adc2019.js +++ b/static/js/adc2019.js @@ -96,7 +96,8 @@ class StatusView { }), contentType: 'application/json' }).done((d) => { - var request_id = d['request_id']; + console.log(d); + // var request_id = d['request_id']; // var timeout = d['timeout']; // _this.container.find('#solver-processing-modal').modal({ diff --git a/templates/part_request_status.html b/templates/part_request_status.html index b0dea2812a631496b9e96b11fd03774e4c6ffa1d..9b7c88022c379f5eaa33c69a91b0ba04dc2617d0 100644 --- a/templates/part_request_status.html +++ b/templates/part_request_status.html @@ -1,19 +1,12 @@
- {% for r in status %} -

処理結果:{{r.status}}

- - {% for k, v in r['worker_status'].items() %} + {% for r in status %} - - + + {% endfor %}
{{k}}{{v}}{{r['worker']}}{{r['status']}}
- {% endfor %}