From 569e20bf92a5f5bf969596792767bb3ad30019a3 Mon Sep 17 00:00:00 2001 From: iteratorlee <1400012951@pku.edu.cn> Date: Wed, 8 Aug 2018 21:48:29 +0800 Subject: [PATCH] add job list viewing --- src/master/httprest.py | 10 ++++++++-- src/master/jobmgr.py | 20 ++++++++++++++++---- web/templates/batch/batch_create.html | 7 +++++++ web/templates/batch/batch_list.html | 12 ++++++++++++ web/webViews/batch.py | 9 +++++++-- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/master/httprest.py b/src/master/httprest.py index 3878a14..6cc412c 100755 --- a/src/master/httprest.py +++ b/src/master/httprest.py @@ -780,12 +780,12 @@ def add_job(user,beans,form): } } job_info["tasks"][task_idx] = tmp_dict - logger.debug('batch job adding form %s' % job_data) logger.debug('batch job adding info %s' % json.dumps(job_info, indent=4)) [status, msg] = G_jobmgr.add_job(user, job_info) if status: return json.dumps(message) else: + logger.debug('fail to add batch job: %s' % msg) message["success"] = "false" message["message"] = msg return json.dumps(message) @@ -794,7 +794,13 @@ def add_job(user,beans,form): @app.route("/batch/job/list/", methods=['POST']) @login_required def list_job(user,beans,form): - pass + global G_jobmgr + result = { + 'status': 'true', + 'data': G_jobmgr.list_jobs(user) + } + return json.dumps(result) + @app.route("/batch/job/info/", methods=['POST']) @login_required diff --git a/src/master/jobmgr.py b/src/master/jobmgr.py index 1ff896e..cb38b4c 100644 --- a/src/master/jobmgr.py +++ b/src/master/jobmgr.py @@ -24,6 +24,8 @@ class BatchJob(object): dependency_graph[task_idx] = set() task_info = tasks[task_idx] dependency = task_info['dependency'].strip().replace(' ', '').split(',') + if len(dependency) == 1 and dependency[0] == '': + continue for t in dependency: if not t in tasks: raise ValueError('task %s is not defined in the dependency of task %s' % (t, task_idx)) @@ -35,9 +37,12 @@ class BatchJob(object): if len(dependency_graph[task_idx]) == 0: flag = True s.add(task_idx) + for task_idx in s: + dependency_graph.pop(task_idx) #there is a circle in the graph if not flag: raise ValueError('there is a circle in the dependency graph') + break for task_idx in dependency_graph: for t in s: if t in dependency_graph[task_idx]: @@ -51,7 +56,7 @@ class BatchJob(object): def get_task(self): for task in self.task_queue: if task['status'] == 'pending': - task_idx = task['task_idx'] + task_idx = task['task_idx'].pop() task['status'] = 'running' task_name = self.user + '_' + self.job_id + '_' + self.task_idx return task_name, self.raw_job_info["tasks"][task_idx] @@ -78,10 +83,12 @@ class JobMgr(object): try: job = BatchJob(user, job_info) job.job_id = self.gen_jobid() - self.job_queue.append(job_id) - self.job_map[job_id] = job + self.job_queue.append(job.job_id) + self.job_map[job.job_id] = job except ValueError as err: return [False, err.args[0]] + except Exception as err: + return [False, err.args[0]] finally: return [True, "add batch job success"] @@ -91,6 +98,7 @@ class JobMgr(object): res = [] for job_id in self.job_queue: job = self.job_map[job_id] + logger.debug('job_id: %s, user: %s' % (job_id, job.user)) if job.user == user: res.append({ 'job_name': job.job_name, @@ -114,7 +122,7 @@ class JobMgr(object): # generate a random job id def gen_jobid(self): job_id = ''.join(random.sample(string.ascii_letters + string.digits, 8)) - while is_job_exist(job_id): + while self.is_job_exist(job_id): job_id = ''.join(random.sample(string.ascii_letters + string.digits, 8)) return job_id @@ -138,3 +146,7 @@ class JobMgr(object): else: job.status = 'done' + # a task has finished + def report(self, task): + pass + diff --git a/web/templates/batch/batch_create.html b/web/templates/batch/batch_create.html index 2c36e58..ed4adec 100644 --- a/web/templates/batch/batch_create.html +++ b/web/templates/batch/batch_create.html @@ -171,6 +171,13 @@ +'
' +'
Seconds' +'
' + +'' + +'
' + +'
' + +'' + +'
' + +'
' + +'
' +'' +'
' +'
' diff --git a/web/templates/batch/batch_list.html b/web/templates/batch/batch_list.html index 5b65179..38eca0f 100644 --- a/web/templates/batch/batch_list.html +++ b/web/templates/batch/batch_list.html @@ -45,6 +45,18 @@ + {% for job_info in job_list %} + + {{ job_info['job_id'] }} + {{ job_info['job_name'] }} + + {{ job_info['status'] }} + + Tasks + + {{ job_info['create_time'] }} + + {% endfor %}
diff --git a/web/webViews/batch.py b/web/webViews/batch.py index 0791613..8c75cc2 100644 --- a/web/webViews/batch.py +++ b/web/webViews/batch.py @@ -1,5 +1,6 @@ from flask import session, redirect, request from webViews.view import normalView +from webViews.log import logger from webViews.checkname import checkname from webViews.dockletrequest import dockletRequest @@ -8,8 +9,12 @@ class batchJobListView(normalView): @classmethod def get(self): + masterips = dockletRequest.post_to_all() + result = dockletRequest.post("/batch/job/list/",{},masterips[0].split("@")[0]) + job_list = result.get("data") + logger.debug("job_list: %s" % job_list) if True: - return self.render(self.template_path) + return self.render(self.template_path, job_list=job_list) else: return self.error() @@ -43,6 +48,6 @@ class addBatchJobView(normalView): masterip = self.masterip result = dockletRequest.post("/batch/job/add/", self.job_data, masterip) if result.get('success', None) == "true": - return self.render(self.template_path) + return redirect('/batch_jobs/') else: return self.error()