Commit bffa7d2f authored by Kento HASEGAWA's avatar Kento HASEGAWA
Browse files

Improve UI and adccli co-operation

parent f3ba4ba7
Loading
Loading
Loading
Loading
+34 −21
Changes for roles/host.py: 34 added lines, 21 removed lines.
Original line number Diff line number Diff line
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:
@@ -379,6 +377,8 @@ class Request(object):
            self.part_nums = 1
            self.solved = [0]
        
        self.is_processed = False

    @property
    def request_data(self):
        data = self.data
@@ -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,35 +423,44 @@ 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 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)}'

                elapsed_time = time.time() - self.request_time
                    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):
+3 −3
Changes for roles/solver.py: 3 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -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:
+6 −4
Changes for static/js/adc2019.js: 6 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -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("ログアウト");
+8 −8
Changes for utils/adcclilib.py: 8 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -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)

+4 −0
Changes for utils/data.py: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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'