Commit 3895ae24 by Enrico Pozzobon

allow user to cancel scheduled or running tests

parent 72e9cc76
......@@ -219,9 +219,11 @@ function showJobMenu(event, jobId) {
const st = schedule[jobId].state;
if (st == 'SUCCESSFUL' || st == 'FAILED') {
menuView.appendChild(makeEntry('↺ Retry', () => restartJob(jobId)));
}
if (st == 'SUCCESSFUL' || st == 'FAILED' || st == 'SCHEDULED') {
menuView.appendChild(makeEntry('🗑️ Delete', () => deleteJob(jobId)));
}
if (st == 'RUNNING' || st == 'SCHEDULED') {
if (st == 'RUNNING') {
menuView.appendChild(makeEntry('🗴 Cancel', () => cancelJob(jobId)));
}
menuView.appendChild(makeEntry('🗎 View Logs', () => viewJobLogs(jobId)));
......
......@@ -64,6 +64,8 @@ class ScheduledTest:
if k not in ScheduledTest._unserialized_slots:
if k != 'id':
setattr(a, k, dict[k])
if a.state == 'RUNNING':
a.state = 'SCHEDULED'
return a
......@@ -81,8 +83,13 @@ class Runner(threading.Thread):
self.program = program
self.process = None
self.job = None
# Event used for stopping the runner
self.stop_event = threading.Event()
# Event used to abort only the current job
self.abort_event = threading.Event()
threading.Thread.__init__(self)
self.name += "-%s" % template
self.start()
......@@ -96,8 +103,12 @@ class Runner(threading.Thread):
}
def stop(self):
self.abort_event.set()
self.stop_event.set()
def abort_current_job(self):
self.abort_event.set()
def lock_new_job(self):
my_queue = [
s for s in schedule
......@@ -124,6 +135,7 @@ class Runner(threading.Thread):
def do_job(self):
self.job.time_started = int(time.time())
self.abort_event.clear()
cmd = []
cmd += self.program
......@@ -139,7 +151,7 @@ class Runner(threading.Thread):
stderr=err_fd
)
while self.process.poll() is None:
if self.stop_event.wait(timeout=1):
if self.abort_event.wait(timeout=1):
self.process.send_signal(signal.SIGINT)
try:
self.process.wait(timeout=1)
......@@ -201,6 +213,27 @@ class DeleteJob(Resource):
return 'Job is already running', 400
class CancelJob(Resource):
def get(self, job_id):
job = [job for job in schedule if job.id == job_id]
job = job[0] if len(job) > 0 else None
if job is None:
return 'Job not found', 404
with job.lock:
if job.state == 'RUNNING':
r = [r for r in runners if r if r.job == job]
if len(r) == 0:
return 'Job runner not found', 404
process = r[0].process
if process is None:
return 'Job runner process not found', 404
process.send_signal(signal.SIGINT)
return jsonify({'success': True})
else:
return 'Job is not running', 400
class RestartJob(Resource):
def get(self, job_id):
job = [job for job in schedule if job.id == job_id]
......@@ -238,6 +271,7 @@ class ScheduleJob(Resource):
api.add_resource(Status, '/status')
api.add_resource(ScheduleJob, '/schedule_test')
api.add_resource(CancelJob, '/cancel_test/<string:job_id>')
api.add_resource(RestartJob, '/restart_test/<string:job_id>')
api.add_resource(DeleteJob, '/delete_test/<string:job_id>')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment