diff --git a/roles/host.py b/roles/host.py index 80ab42757fcea53e52701823825b6aa0b9430dd2..6858d269b46f45ede09a73e5682a185373e5454d 100644 --- a/roles/host.py +++ b/roles/host.py @@ -1,5 +1,6 @@ import glob import json +import os import sys import threading import time @@ -207,6 +208,9 @@ class Host(object): return {'status': 'stopped'} elif cmd == 'worker/status': self.worker_manager.update_status(params['address'], params['status']) + if 'request_id' in params['params']: + request_id = params['params']['request_id'] + self.request[request_id].set_running() return {'status': 'updated'} elif cmd == 'view': problem_key = params['problem'] @@ -219,28 +223,28 @@ class Host(object): r = adccli.logout() return {'status': r} elif cmd == 'adccli/whoami': - r = adccli.whoami() - return {'message': r, 'status': r == self.config['adccli']} + r = adccli.whoami().strip() + return {'status': r, 'is_logged_in': r == self.config['adccli']['username']} elif cmd == 'adccli/download-problem': - out_abspath = os.path.abspath(self.config['problem_path']) + out_abspath = os.path.abspath(os.path.dirname(self.config['problem_path'])) r = adccli.get_q_all(out_abspath) self._load_problems(self.config['problem_path']) return {'status': r} elif cmd == 'adccli/upload-solution': problem_key = params['problem'] problem = self.problems[problem_key] - if problem.best_solution_key is None: + if problem.best_solution is None: res = {'status': "Required to 'save' before submission"} else: - solution_path = f"{self.config['solution_path']}/{problem_key}/submit/{problem_key}.txt" - qnumber = problem_key.replace("NL_Q", "").replace(".txt", "") + solution_path = f"{self.config['solution_path']}/submit/{problem_key}.txt" + qnumber = problem_key.replace("Q", "").replace(".txt", "") solution_abspath = os.path.abspath(solution_path) r = adccli.put_a(qnumber, solution_abspath) mes = r + "\n" - best_solution_key = problem.best_solution_key + best_solution_key = problem.best_solution best_solution = problem.get_solution(best_solution_key) cputime = f'{best_solution.elapsed_time:.3f}' info_mes = f'Solver: {best_solution.worker}, RID: {best_solution.request_id}' @@ -359,17 +363,11 @@ class Request(object): self.request_id = time.time() self.request_time = None + self.start_time = None self.done_time = None - # 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() self.response = list() if self.solver.partial_mode: @@ -378,6 +376,8 @@ class Request(object): else: self.part_nums = 1 self.solved = [0] + + self.is_processed = False @property def request_data(self): @@ -392,6 +392,10 @@ class Request(object): def get_dict(self): return self.request_data + def set_running(self): + self.is_processed = True + self.start_time = time.time() + def store_response(self, data): # worker = data['worker'] # self.response[worker].append(data) @@ -419,36 +423,45 @@ class Request(object): status = '' if self.solved[-1] == 1: - elapsed_time = self.done_time - self.request_time + 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'done ({self.solved[-1]}) [{et_minutes}:{et_seconds:02}]' elif self.solved[-1] == -1: - status = 'failed' + 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}]' else: if self.solver.status == 'Not connected': status = 'Not connected' else: - 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)}' - - 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}]' + if self.is_processed: + 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)}' + + if self.start_time is None: + self.start_time = time.time() + elapsed_time = time.time() - self.start_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}]' + else: + status = 'Queued' return { 'status': status, - 'worker': self.solver.address, - # 'solutions': response_count, - # 'progress': progress, - # 'worker_status': worker_status - } + 'worker': self.solver.address + } def broadcast(self): diff --git a/roles/solver.py b/roles/solver.py index 963ae92eeabcaa4e9f12bdbfa0aceb519193e3d0..5745d103df7798ff95ad48374ce06b3cdff76660 100644 --- a/roles/solver.py +++ b/roles/solver.py @@ -37,9 +37,9 @@ class Solver(object): def __repr__(self): return "Solver" - def set_status(self, status): + def set_status(self, status, params=dict()): self.status = status - self.post('worker/status', {'address': self.address, 'status': self.status}) + self.post('worker/status', {'address': self.address, 'status': self.status, 'params': params}) def solver_thread(self): @@ -48,7 +48,7 @@ class Solver(object): print("I: Solver started") _, params = self.queue.popitem(last=False) self.solving = params - self.set_status(f'Running ({len(self.queue)} in queue)') + self.set_status(f'Running ({len(self.queue)} in queue)', params={'request_id': params['request_id']}) try: self.solve(params) except Exception as e: diff --git a/static/js/adc2019.js b/static/js/adc2019.js index 6f24286f51439f9b7a399445a8f861ae6b774497..336bfe2a9d15011ebe2b0707f1bdd48f91248c36 100644 --- a/static/js/adc2019.js +++ b/static/js/adc2019.js @@ -42,7 +42,7 @@ class StatusView { }); _this.container.find('.submit-button').click(()=>{ - _this.save_solution(); + _this.upload_solution(); }); _this.container.find('#chk-solver-all').prop('checked', false); @@ -162,7 +162,7 @@ class StatusView { }), contentType: 'application/json' }).done((d) => { - alert(d); + alert(d['status']); }); } @@ -208,6 +208,8 @@ class StatusView { _this.container.empty(); _this.container.html(d); + clearInterval(_this.request_refresh_timer); + var button_action_with_ajax = function($obj, url){ $obj.prop("disabled", "disabled"); $.ajax({ @@ -216,7 +218,7 @@ class StatusView { dataType: "json", }).done((data)=>{ $obj.prop("disabled", false); - alert(data['message']); + alert(data['status']); }); }; @@ -262,7 +264,7 @@ class StatusView { url: "/api/adccli/whoami", dataType: "json", }).done((data)=>{ - if(data['status']) + if(data['is_logged_in']) $("#adccli-status").text("ログイン中"); else $("#adccli-status").text("ログアウト"); diff --git a/utils/adcclilib.py b/utils/adcclilib.py index de332abbdd482f3e9b08e3e92f37ea9119ce92a8..9547364a655933cb540e3eaf133ad47a680f40ca 100644 --- a/utils/adcclilib.py +++ b/utils/adcclilib.py @@ -8,9 +8,8 @@ ADCCLI = f"{BASEDIR}/../adc2019/client/adccli" def _exec_adccli(cmd): exec_cmd = f"{PYTHON_BIN} {ADCCLI} {cmd}".strip() print("ADCCLI: {}".format(exec_cmd)) - # p = subprocess.run(exec_cmd, stdout=subprocess.PIPE, shell=True) - # res = p.stdout.decode().strip() - res = '' + p = subprocess.run(exec_cmd, stdout=subprocess.PIPE, shell=True) + res = p.stdout.decode().strip() print(res) return res @@ -27,7 +26,7 @@ def whoami(): return _exec_adccli(cmd) def put_message(message): - cmd = "put-user-alive '{}'" + cmd = "put-user-alile '{}'" return _exec_adccli(cmd) def post_user_q(qnum, filepath): @@ -41,10 +40,11 @@ def get_q_all(outpath): print("--- ADCCLI questions ---") print(question_list) - for v in question_list: - if v.startswith("Q"): - qnumber = int(v.replace("Q", "")) - out_file_path = "{}/NL_Q{:02d}.txt".format(outpath, qnumber) + for l in question_list: + if l.startswith("Q"): + v = l.split() + qnumber = int(v[0].replace("Q", "")) + out_file_path = "{}/Q{:02d}.txt".format(outpath, qnumber) cmd = "--output {} get-q {}".format(out_file_path, qnumber) r = _exec_adccli(cmd) diff --git a/utils/data.py b/utils/data.py index 460a9b3b4e421769aa320f537e79ca80e3dee449..bc5ee62904f136cc54f67221361bf5a0e09fc0fc 100644 --- a/utils/data.py +++ b/utils/data.py @@ -525,6 +525,10 @@ class Solution(object): else: return '-' + @property + def nlcheck_str(self): + return f'{self.nlcheck:.4f}' + def is_valid_solution(self): return self.status == 'done'