From ba0a143717df8e53c0ce15a56cf467a4646247ec Mon Sep 17 00:00:00 2001 From: Massimo Date: Tue, 12 Mar 2013 10:40:57 -0500 Subject: [PATCH] scheduler patch allows termination of tasks, thanks niphlod --- VERSION | 2 +- .../examples/views/default/index.html | 2 +- gluon/scheduler.py | 42 ++++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index b8817a22..d996401e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.4.4-stable+timestamp.2013.03.11.18.11.19 +Version 2.4.4-stable+timestamp.2013.03.12.10.40.02 diff --git a/applications/examples/views/default/index.html b/applications/examples/views/default/index.html index 7fa52397..f99d2ca4 100644 --- a/applications/examples/views/default/index.html +++ b/applications/examples/views/default/index.html @@ -43,7 +43,7 @@ random.shuffle(quotes)
Download Now
Online Demo
- Sites Powereb by web2py + Sites Powered by web2py diff --git a/gluon/scheduler.py b/gluon/scheduler.py index 621522f6..26c54089 100644 --- a/gluon/scheduler.py +++ b/gluon/scheduler.py @@ -107,6 +107,7 @@ TERMINATE = 'TERMINATE' DISABLED = 'DISABLED' KILL = 'KILL' PICK = 'PICK' +STOP_TASK = 'STOP_TASK' EXPIRED = 'EXPIRED' SECONDS = 1 HEARTBEAT = 3 * SECONDS @@ -398,7 +399,7 @@ class MetaScheduler(threading.Thread): TASK_STATUS = (QUEUED, RUNNING, COMPLETED, FAILED, TIMEOUT, STOPPED, EXPIRED) RUN_STATUS = (RUNNING, COMPLETED, FAILED, TIMEOUT, STOPPED) -WORKER_STATUS = (ACTIVE, PICK, DISABLED, TERMINATE, KILL) +WORKER_STATUS = (ACTIVE, PICK, DISABLED, TERMINATE, KILL, STOP_TASK) class TYPE(object): @@ -746,7 +747,7 @@ class Scheduler(MetaScheduler): # keep sleeping self.worker_status[0] = DISABLED if self.worker_status[1] == MAXHIBERNATION: - logger.debug('........recording heartbeat') + logger.debug('........recording heartbeat (%s)', self.worker_status[0]) db(sw.worker_name == self.worker_name).update( last_heartbeat=now) elif mybackedstatus == TERMINATE: @@ -758,6 +759,9 @@ class Scheduler(MetaScheduler): self.worker_status[0] = KILL self.die() else: + if mybackedstatus == STOP_TASK: + logger.info('Asked to kill the current task') + self.terminate_process() logger.debug('........recording heartbeat (%s)', self.worker_status[0]) db(sw.worker_name == self.worker_name).update( last_heartbeat=now, status=ACTIVE) @@ -1007,6 +1011,40 @@ class Scheduler(MetaScheduler): object_hook=_decode_dict) or None return row + def stop_task(self, ref): + """ + Experimental!!! + Shortcut for task termination. + If the task is RUNNING it will terminate it --> execution will be set as FAILED + If the task is QUEUED, its stop_time will be set as to "now", + the enabled flag will be set to False, status to STOPPED + + :param ref: can be + - integer --> lookup will be done by scheduler_task.id + - string --> lookup will be done by scheduler_task.uuid + Returns: + - 1 if task was stopped (meaning an update has been done) + - None if task was not found, or if task was not RUNNING or QUEUED + """ + from gluon.dal import Query + st, sw = self.db.scheduler_task, self.db.scheduler_worker + if isinstance(ref, int): + q = st.id == ref + elif isinstance(ref, str): + q = st.uuid == ref + else: + raise SyntaxError( + "You can retrieve results only by id or uuid") + task = self.db(q).select(st.id, st.status, st.assigned_worker_name).first() + rtn = None + if not task: + return rtn + if task.status == 'RUNNING': + rtn = self.db(sw.worker_name == task.assigned_worker_name).update(status=STOP_TASK) + elif task.status == 'QUEUED': + rtn = self.db(q).update(stop_time=self.now(), enabled=False, status=STOPPED) + return rtn + def main(): """