diff --git a/roles/host.py b/roles/host.py index 5bd84f79aca23fdb1797b05c78a6e914b9e40054..cab5836a3d4196d3caca2d135e9be766a037b3d8 100644 --- a/roles/host.py +++ b/roles/host.py @@ -147,6 +147,9 @@ class Host(object): elif cmd == 'stop': self.worker_manager.request_stop() return {} + elif cmd == 'cancel': + self.worker_manager.request_cancel(params) + return {'status': 'canceled'} elif cmd == 'worker/status': self.worker_manager.update_status(params['address'], params['status']) return {'status': 'updated'} @@ -232,6 +235,9 @@ class WorkerManager(object): def request_stop(self): self.broadcast('stop', {}) + + def request_cancel(self, params): + self.broadcast('cancel', params) def broadcast(self, cmd, params, solvers=None): diff --git a/roles/solver.py b/roles/solver.py index 69427077f56013b9f3e942dc3d6a88528a530a28..2343f35fadd3b2165c38094f5a79d301d817ed85 100644 --- a/roles/solver.py +++ b/roles/solver.py @@ -19,9 +19,10 @@ class Solver(object): self.solver = importlib.import_module(f"solvers.{config['solver']}") self.queue = OrderedDict() + self.solving = None + self.status = None - # self.thread = None self.thread = threading.Thread(name='solver', target=self.solver_thread, daemon=True) self.thread.start() @@ -43,14 +44,15 @@ class Solver(object): if len(self.queue) > 0: print("I: Solver started") _, params = self.queue.popitem(last=False) - # self.status = f'Running ({len(self.queue)} in queue)' + self.solving = params self.set_status(f'Running ({len(self.queue)} in queue)') - self.solve(params) - # self.status = 'Ready' + try: + self.solve(params) + except Exception as e: + print("E: An error has occurred in the solver thread") + self.solving = None self.set_status('Ready') else: - # self.status = 'Ready' - self.set_status('Ready') time.sleep(0.5) def solve(self, params): @@ -65,7 +67,7 @@ class Solver(object): solution['elapsed_time'] = elapsed_time self.submit_solution(params, solution) - # self.thread = None + return True def post(self, path, data): @@ -94,16 +96,35 @@ class Solver(object): print("I: Problem queued") _id = params['request_id'] self.queue[_id] = params - # self.status = f'Running ({len(self.queue)} in queue)' self.set_status(f'Running ({len(self.queue)} in queue)') return {'status': self.status} def stop_solver(self): - if self.thread is not None: - self.solver.stop() + # if self.thread is not None: + # self.solver.stop() + self.solver.stop() return {'status': self.status} + + def cancel_queue(self, params): + + if 'request_id' in params: + request_id = params['request'] + for k, v in self.queue.items(): + if k == request_id: + self.queue.pop(k, None) + if self.solving['request_id'] == request_id: + self.solver.stop()() + elif 'problem' in params: + problem_name = params['problem'] + for k, v in self.queue.items(): + if v['name'] == problem_name: + self.queue.pop(k, None) + if self.solving['name'] == problem_name: + self.solver.stop()() + + return {'status': 'canceled'} def call_api(self, method, cmd, params): if cmd == 'role': @@ -112,6 +133,8 @@ class Solver(object): return self.start_solver(params) elif cmd == 'stop': return self.stop_solver() + elif cmd == 'cancel': + return self.cancel_queue(params) elif cmd == 'status': return {'status': self.status} else: diff --git a/static/js/adc2019.js b/static/js/adc2019.js index 369233894841a2cd975519f41a4c17fc237220f1..3708073ddc9556af40e9a2251cd63d2a0462d615 100644 --- a/static/js/adc2019.js +++ b/static/js/adc2019.js @@ -30,6 +30,10 @@ class StatusView { _this.start_solver(); }); + _this.container.find('.cancel-button').click(()=>{ + _this.cancel_problem(); + }); + _this.container.find('.save-button').click(()=>{ _this.save_solution(); _this.fire('refresh'); @@ -112,6 +116,28 @@ class StatusView { }); } + cancel_problem(){ + var _this = this; + + var _button = _this.container.find('.cancel-button') + _button.html('Loading...'); + _button.prop('disabled', 'disabled'); + + $.ajax({ + type: "POST", + dataType: "json", + url: "/api/cancel", + data: JSON.stringify({ + "problem": _this.problem_key, + }), + contentType: 'application/json' + }).done((d) => { + _button.prop('disabled', false); + _button.text('Cancel'); + console.log(d); + }); + } + // 強制停止 stop_solver(){ var _this = this; diff --git a/templates/part_problem_status.html b/templates/part_problem_status.html index eca4f65049977b6f026c9d5bcaf3c989be8aa887..64aef0e93943e106c2eaa38cca7820069e755b3d 100644 --- a/templates/part_problem_status.html +++ b/templates/part_problem_status.html @@ -1,13 +1,13 @@

{{problem.name}}

- Viewer {#% # if localmode %#} - + {#% else %#} + Viewer {#% endif %#}