Loading roles/host.py +6 −0 Changes for roles/host.py: 6 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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'} Loading Loading @@ -233,6 +236,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): threads = [] Loading roles/solver.py +31 −8 Changes for roles/solver.py: 31 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -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() Loading @@ -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)') try: self.solve(params) # self.status = 'Ready' 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): Loading @@ -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): Loading Loading @@ -94,17 +96,36 @@ 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: # 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': return {'role': self.type} Loading @@ -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: Loading static/js/adc2019.js +26 −0 Changes for static/js/adc2019.js: 26 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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'); Loading Loading @@ -112,6 +116,28 @@ class StatusView { }); } cancel_problem(){ var _this = this; var _button = _this.container.find('.cancel-button') _button.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span><span class="sr-only">Loading...</span>'); _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; Loading templates/part_problem_status.html +2 −2 Changes for templates/part_problem_status.html: 2 added lines, 2 removed lines. Original line number Diff line number Diff line <div> <h4 class='inline-heading' id='problem-status-title'>{{problem.name}}</h4> <a href="/viewer#{{problem.name}}" target="_blank">Viewer</a> {#% # if localmode %#} <button class="btn btn-primary btn-lg start-button" type="button" data-qname="{{problem.name}}">Start</button> <!-- <button class="btn btn-danger btn-lg stop-button" type="button" data-qname="all">Stop</button> --> <button class="btn btn-danger btn-lg cancel-button" type="button" data-qname="{{problem.name}}">Cancel</button> <button class="btn btn-info btn-lg save-button" type="button" data-qname="{{problem.name}}">Save</button> <button class="btn btn-success btn-lg submit-button" type="button" data-qname="{{problem.name}}">Up</button> {#% else %#} <!-- [View Only] --> <a class="btn btn-outline-success btn-lg" href="/viewer#{{problem.name}}" role="button" target='_blank'>Viewer</a> {#% endif %#} </div> Loading Loading
roles/host.py +6 −0 Changes for roles/host.py: 6 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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'} Loading Loading @@ -233,6 +236,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): threads = [] Loading
roles/solver.py +31 −8 Changes for roles/solver.py: 31 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -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() Loading @@ -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)') try: self.solve(params) # self.status = 'Ready' 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): Loading @@ -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): Loading Loading @@ -94,17 +96,36 @@ 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: # 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': return {'role': self.type} Loading @@ -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: Loading
static/js/adc2019.js +26 −0 Changes for static/js/adc2019.js: 26 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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'); Loading Loading @@ -112,6 +116,28 @@ class StatusView { }); } cancel_problem(){ var _this = this; var _button = _this.container.find('.cancel-button') _button.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span><span class="sr-only">Loading...</span>'); _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; Loading
templates/part_problem_status.html +2 −2 Changes for templates/part_problem_status.html: 2 added lines, 2 removed lines. Original line number Diff line number Diff line <div> <h4 class='inline-heading' id='problem-status-title'>{{problem.name}}</h4> <a href="/viewer#{{problem.name}}" target="_blank">Viewer</a> {#% # if localmode %#} <button class="btn btn-primary btn-lg start-button" type="button" data-qname="{{problem.name}}">Start</button> <!-- <button class="btn btn-danger btn-lg stop-button" type="button" data-qname="all">Stop</button> --> <button class="btn btn-danger btn-lg cancel-button" type="button" data-qname="{{problem.name}}">Cancel</button> <button class="btn btn-info btn-lg save-button" type="button" data-qname="{{problem.name}}">Save</button> <button class="btn btn-success btn-lg submit-button" type="button" data-qname="{{problem.name}}">Up</button> {#% else %#} <!-- [View Only] --> <a class="btn btn-outline-success btn-lg" href="/viewer#{{problem.name}}" role="button" target='_blank'>Viewer</a> {#% endif %#} </div> Loading