scheduler.queue_task(...), thanks Niphlod
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 2.1.1 (2012-10-17 17:00:46) dev
|
Version 2.1.1 (2012-10-18 13:02:13) dev
|
||||||
|
|||||||
+94
-44
@@ -87,6 +87,7 @@ try:
|
|||||||
except:
|
except:
|
||||||
from simplejson import loads, dumps
|
from simplejson import loads, dumps
|
||||||
|
|
||||||
|
logger = logging.getLogger('web2py.scheduler')
|
||||||
|
|
||||||
from gluon import DAL, Field, IS_NOT_EMPTY, IS_IN_SET, IS_NOT_IN_DB, IS_INT_IN_RANGE, IS_DATETIME
|
from gluon import DAL, Field, IS_NOT_EMPTY, IS_IN_SET, IS_NOT_IN_DB, IS_INT_IN_RANGE, IS_DATETIME
|
||||||
from gluon.utils import web2py_uuid
|
from gluon.utils import web2py_uuid
|
||||||
@@ -115,7 +116,7 @@ CALLABLETYPES = (types.LambdaType, types.FunctionType,
|
|||||||
|
|
||||||
class Task(object):
|
class Task(object):
|
||||||
def __init__(self,app,function,timeout,args='[]',vars='{}',**kwargs):
|
def __init__(self,app,function,timeout,args='[]',vars='{}',**kwargs):
|
||||||
logging.debug(' new task allocated: %s.%s' % (app,function))
|
logger.debug(' new task allocated: %s.%s' % (app,function))
|
||||||
self.app = app
|
self.app = app
|
||||||
self.function = function
|
self.function = function
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
@@ -127,11 +128,11 @@ class Task(object):
|
|||||||
|
|
||||||
class TaskReport(object):
|
class TaskReport(object):
|
||||||
def __init__(self,status,result=None,output=None,tb=None):
|
def __init__(self,status,result=None,output=None,tb=None):
|
||||||
logging.debug(' new task report: %s' % status)
|
logger.debug(' new task report: %s' % status)
|
||||||
if tb:
|
if tb:
|
||||||
logging.debug(' traceback: %s' % tb)
|
logger.debug(' traceback: %s' % tb)
|
||||||
else:
|
else:
|
||||||
logging.debug(' result: %s' % result)
|
logger.debug(' result: %s' % result)
|
||||||
self.status = status
|
self.status = status
|
||||||
self.result = result
|
self.result = result
|
||||||
self.output = output
|
self.output = output
|
||||||
@@ -173,7 +174,7 @@ def _decode_dict(dct):
|
|||||||
|
|
||||||
def executor(queue,task, out):
|
def executor(queue,task, out):
|
||||||
""" the background process """
|
""" the background process """
|
||||||
logging.debug(' task started')
|
logger.debug(' task started')
|
||||||
|
|
||||||
class LogOutput(object):
|
class LogOutput(object):
|
||||||
"""Facility to log output at intervals"""
|
"""Facility to log output at intervals"""
|
||||||
@@ -248,7 +249,7 @@ class MetaScheduler(threading.Thread):
|
|||||||
queue = multiprocessing.Queue(maxsize=1)
|
queue = multiprocessing.Queue(maxsize=1)
|
||||||
p = multiprocessing.Process(target=executor,args=(queue,task,out))
|
p = multiprocessing.Process(target=executor,args=(queue,task,out))
|
||||||
self.process = p
|
self.process = p
|
||||||
logging.debug(' task starting')
|
logger.debug(' task starting')
|
||||||
p.start()
|
p.start()
|
||||||
|
|
||||||
task_output = ""
|
task_output = ""
|
||||||
@@ -266,7 +267,7 @@ class MetaScheduler(threading.Thread):
|
|||||||
not task.timeout or time.time()-start < task.timeout):
|
not task.timeout or time.time()-start < task.timeout):
|
||||||
if tout:
|
if tout:
|
||||||
try:
|
try:
|
||||||
logging.debug(' partial output saved')
|
logger.debug(' partial output saved')
|
||||||
db(sr.id==task.run_id).update(output = task_output)
|
db(sr.id==task.run_id).update(output = task_output)
|
||||||
db.commit()
|
db.commit()
|
||||||
except:
|
except:
|
||||||
@@ -276,7 +277,7 @@ class MetaScheduler(threading.Thread):
|
|||||||
while not out.empty():
|
while not out.empty():
|
||||||
tout += out.get()
|
tout += out.get()
|
||||||
if tout:
|
if tout:
|
||||||
logging.debug(' partial output: "%s"' % str(tout))
|
logger.debug(' partial output: "%s"' % str(tout))
|
||||||
if CLEAROUT in tout:
|
if CLEAROUT in tout:
|
||||||
task_output = tout[tout.rfind(CLEAROUT)+len(CLEAROUT):]
|
task_output = tout[tout.rfind(CLEAROUT)+len(CLEAROUT):]
|
||||||
else:
|
else:
|
||||||
@@ -285,12 +286,12 @@ class MetaScheduler(threading.Thread):
|
|||||||
p.terminate()
|
p.terminate()
|
||||||
p.join()
|
p.join()
|
||||||
self.have_heartbeat = False
|
self.have_heartbeat = False
|
||||||
logging.debug(' task stopped by general exception')
|
logger.debug(' task stopped by general exception')
|
||||||
tr = TaskReport(STOPPED)
|
tr = TaskReport(STOPPED)
|
||||||
else:
|
else:
|
||||||
if p.is_alive():
|
if p.is_alive():
|
||||||
p.terminate()
|
p.terminate()
|
||||||
logging.debug(' task timeout')
|
logger.debug(' task timeout')
|
||||||
try:
|
try:
|
||||||
# we try to get a traceback here
|
# we try to get a traceback here
|
||||||
tr = queue.get(timeout=2)
|
tr = queue.get(timeout=2)
|
||||||
@@ -300,21 +301,21 @@ class MetaScheduler(threading.Thread):
|
|||||||
tr = TaskReport(TIMEOUT)
|
tr = TaskReport(TIMEOUT)
|
||||||
elif queue.empty():
|
elif queue.empty():
|
||||||
self.have_heartbeat = False
|
self.have_heartbeat = False
|
||||||
logging.debug(' task stopped')
|
logger.debug(' task stopped')
|
||||||
tr = TaskReport(STOPPED)
|
tr = TaskReport(STOPPED)
|
||||||
else:
|
else:
|
||||||
logging.debug(' task completed or failed')
|
logger.debug(' task completed or failed')
|
||||||
tr = queue.get()
|
tr = queue.get()
|
||||||
tr.output = task_output
|
tr.output = task_output
|
||||||
return tr
|
return tr
|
||||||
|
|
||||||
def die(self):
|
def die(self):
|
||||||
logging.info('die!')
|
logger.info('die!')
|
||||||
self.have_heartbeat = False
|
self.have_heartbeat = False
|
||||||
self.terminate_process()
|
self.terminate_process()
|
||||||
|
|
||||||
def give_up(self):
|
def give_up(self):
|
||||||
logging.info('Giving up as soon as possible!')
|
logger.info('Giving up as soon as possible!')
|
||||||
self.have_heartbeat = False
|
self.have_heartbeat = False
|
||||||
|
|
||||||
def terminate_process(self):
|
def terminate_process(self):
|
||||||
@@ -356,18 +357,18 @@ class MetaScheduler(threading.Thread):
|
|||||||
try:
|
try:
|
||||||
self.start_heartbeats()
|
self.start_heartbeats()
|
||||||
while True and self.have_heartbeat:
|
while True and self.have_heartbeat:
|
||||||
logging.debug('looping...')
|
logger.debug('looping...')
|
||||||
task = self.pop_task()
|
task = self.pop_task()
|
||||||
if task:
|
if task:
|
||||||
self.empty_runs = 0
|
self.empty_runs = 0
|
||||||
self.report_task(task,self.async(task))
|
self.report_task(task,self.async(task))
|
||||||
else:
|
else:
|
||||||
self.empty_runs += 1
|
self.empty_runs += 1
|
||||||
logging.debug('sleeping...')
|
logger.debug('sleeping...')
|
||||||
if self.max_empty_runs != 0:
|
if self.max_empty_runs != 0:
|
||||||
logging.debug('empty runs %s/%s', self.empty_runs, self.max_empty_runs)
|
logger.debug('empty runs %s/%s', self.empty_runs, self.max_empty_runs)
|
||||||
if self.empty_runs >= self.max_empty_runs:
|
if self.empty_runs >= self.max_empty_runs:
|
||||||
logging.info('empty runs limit reached, killing myself')
|
logger.info('empty runs limit reached, killing myself')
|
||||||
self.die()
|
self.die()
|
||||||
self.sleep()
|
self.sleep()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
@@ -412,7 +413,7 @@ class Scheduler(MetaScheduler):
|
|||||||
self.db = db
|
self.db = db
|
||||||
self.db_thread = None
|
self.db_thread = None
|
||||||
self.tasks = tasks
|
self.tasks = tasks
|
||||||
self.group_names = group_names or ['main']
|
self.group_names = group_names
|
||||||
self.heartbeat = heartbeat
|
self.heartbeat = heartbeat
|
||||||
self.worker_name = worker_name or socket.gethostname()+'#'+str(os.getpid())
|
self.worker_name = worker_name or socket.gethostname()+'#'+str(os.getpid())
|
||||||
self.worker_status = RUNNING, 1 #tuple containing status as recorded in
|
self.worker_status = RUNNING, 1 #tuple containing status as recorded in
|
||||||
@@ -442,7 +443,7 @@ class Scheduler(MetaScheduler):
|
|||||||
|
|
||||||
def define_tables(self,db,migrate):
|
def define_tables(self,db,migrate):
|
||||||
from gluon.dal import DEFAULT
|
from gluon.dal import DEFAULT
|
||||||
logging.debug('defining tables (migrate=%s)' % migrate)
|
logger.debug('defining tables (migrate=%s)' % migrate)
|
||||||
now = self.now
|
now = self.now
|
||||||
db.define_table(
|
db.define_table(
|
||||||
'scheduler_task',
|
'scheduler_task',
|
||||||
@@ -513,25 +514,25 @@ class Scheduler(MetaScheduler):
|
|||||||
self.start_heartbeats()
|
self.start_heartbeats()
|
||||||
while True and self.have_heartbeat:
|
while True and self.have_heartbeat:
|
||||||
if self.worker_status[0] == DISABLED:
|
if self.worker_status[0] == DISABLED:
|
||||||
logging.debug('Someone stopped me, sleeping until better times come (%s)' % self.worker_status[1])
|
logger.debug('Someone stopped me, sleeping until better times come (%s)' % self.worker_status[1])
|
||||||
self.sleep()
|
self.sleep()
|
||||||
continue
|
continue
|
||||||
logging.debug('looping...')
|
logger.debug('looping...')
|
||||||
task = self.pop_task()
|
task = self.pop_task()
|
||||||
if task:
|
if task:
|
||||||
self.empty_runs = 0
|
self.empty_runs = 0
|
||||||
self.report_task(task,self.async(task))
|
self.report_task(task,self.async(task))
|
||||||
else:
|
else:
|
||||||
self.empty_runs += 1
|
self.empty_runs += 1
|
||||||
logging.debug('sleeping...')
|
logger.debug('sleeping...')
|
||||||
if self.max_empty_runs != 0:
|
if self.max_empty_runs != 0:
|
||||||
logging.debug('empty runs %s/%s', self.empty_runs, self.max_empty_runs)
|
logger.debug('empty runs %s/%s', self.empty_runs, self.max_empty_runs)
|
||||||
if self.empty_runs >= self.max_empty_runs:
|
if self.empty_runs >= self.max_empty_runs:
|
||||||
logging.info('empty runs limit reached, killing myself')
|
logger.info('empty runs limit reached, killing myself')
|
||||||
self.die()
|
self.die()
|
||||||
self.sleep()
|
self.sleep()
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
logging.info('catched')
|
logger.info('catched')
|
||||||
self.die()
|
self.die()
|
||||||
|
|
||||||
def pop_task(self):
|
def pop_task(self):
|
||||||
@@ -548,7 +549,7 @@ class Scheduler(MetaScheduler):
|
|||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
logging.error('TICKER: error assigning tasks')
|
logger.error('TICKER: error assigning tasks')
|
||||||
return None
|
return None
|
||||||
db.commit()
|
db.commit()
|
||||||
grabbed = db(ts.assigned_worker_name==self.worker_name)\
|
grabbed = db(ts.assigned_worker_name==self.worker_name)\
|
||||||
@@ -559,9 +560,9 @@ class Scheduler(MetaScheduler):
|
|||||||
task.update_record(status=RUNNING,last_run_time=now)
|
task.update_record(status=RUNNING,last_run_time=now)
|
||||||
#noone will touch my task!
|
#noone will touch my task!
|
||||||
db.commit()
|
db.commit()
|
||||||
logging.debug(' work to do %s' % task.id)
|
logger.debug(' work to do %s' % task.id)
|
||||||
else:
|
else:
|
||||||
logging.debug('nothing to do')
|
logger.debug('nothing to do')
|
||||||
return None
|
return None
|
||||||
next_run_time = task.last_run_time + datetime.timedelta(seconds=task.period)
|
next_run_time = task.last_run_time + datetime.timedelta(seconds=task.period)
|
||||||
times_run = task.times_run + 1
|
times_run = task.times_run + 1
|
||||||
@@ -571,7 +572,7 @@ class Scheduler(MetaScheduler):
|
|||||||
run_again = False
|
run_again = False
|
||||||
run_id = 0
|
run_id = 0
|
||||||
while True and not self.discard_results:
|
while True and not self.discard_results:
|
||||||
logging.debug(' new scheduler_run record')
|
logger.debug(' new scheduler_run record')
|
||||||
try:
|
try:
|
||||||
run_id = db.scheduler_run.insert(
|
run_id = db.scheduler_run.insert(
|
||||||
scheduler_task = task.id,
|
scheduler_task = task.id,
|
||||||
@@ -582,7 +583,7 @@ class Scheduler(MetaScheduler):
|
|||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
logging.info('new task %(id)s "%(task_name)s" %(application_name)s.%(function_name)s' % task)
|
logger.info('new task %(id)s "%(task_name)s" %(application_name)s.%(function_name)s' % task)
|
||||||
return Task(
|
return Task(
|
||||||
app = task.application_name,
|
app = task.application_name,
|
||||||
function = task.function_name,
|
function = task.function_name,
|
||||||
@@ -609,7 +610,7 @@ class Scheduler(MetaScheduler):
|
|||||||
#result is 'null' as a string if task completed
|
#result is 'null' as a string if task completed
|
||||||
#if it's stopped it's None as NoneType, so we record
|
#if it's stopped it's None as NoneType, so we record
|
||||||
#the STOPPED "run" anyway
|
#the STOPPED "run" anyway
|
||||||
logging.debug(' recording task report in db (%s)' % task_report.status)
|
logger.debug(' recording task report in db (%s)' % task_report.status)
|
||||||
db(db.scheduler_run.id==task.run_id).update(
|
db(db.scheduler_run.id==task.run_id).update(
|
||||||
status = task_report.status,
|
status = task_report.status,
|
||||||
stop_time = now,
|
stop_time = now,
|
||||||
@@ -617,7 +618,7 @@ class Scheduler(MetaScheduler):
|
|||||||
output = task_report.output,
|
output = task_report.output,
|
||||||
traceback = task_report.tb)
|
traceback = task_report.tb)
|
||||||
else:
|
else:
|
||||||
logging.debug(' deleting task report in db because of no result')
|
logger.debug(' deleting task report in db because of no result')
|
||||||
db(db.scheduler_run.id==task.run_id).delete()
|
db(db.scheduler_run.id==task.run_id).delete()
|
||||||
is_expired = (task.stop_time
|
is_expired = (task.stop_time
|
||||||
and task.next_run_time > task.stop_time
|
and task.next_run_time > task.stop_time
|
||||||
@@ -647,7 +648,7 @@ class Scheduler(MetaScheduler):
|
|||||||
next_run_time = task.next_run_time,
|
next_run_time = task.next_run_time,
|
||||||
status=status)
|
status=status)
|
||||||
db.commit()
|
db.commit()
|
||||||
logging.info('task completed (%s)' % task_report.status)
|
logger.info('task completed (%s)' % task_report.status)
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
@@ -659,7 +660,7 @@ class Scheduler(MetaScheduler):
|
|||||||
|
|
||||||
def send_heartbeat(self,counter):
|
def send_heartbeat(self,counter):
|
||||||
if not self.db_thread:
|
if not self.db_thread:
|
||||||
logging.debug('thread building own DAL object')
|
logger.debug('thread building own DAL object')
|
||||||
self.db_thread = DAL(self.db._uri,folder = self.db._adapter.folder)
|
self.db_thread = DAL(self.db._uri,folder = self.db._adapter.folder)
|
||||||
self.define_tables(self.db_thread,migrate=False)
|
self.define_tables(self.db_thread,migrate=False)
|
||||||
try:
|
try:
|
||||||
@@ -679,13 +680,13 @@ class Scheduler(MetaScheduler):
|
|||||||
if mybackedstatus.status == DISABLED:
|
if mybackedstatus.status == DISABLED:
|
||||||
self.worker_status = DISABLED, self.worker_status[1]#keep sleeping
|
self.worker_status = DISABLED, self.worker_status[1]#keep sleeping
|
||||||
if self.worker_status[1] == MAXHIBERNATION:
|
if self.worker_status[1] == MAXHIBERNATION:
|
||||||
logging.debug('........recording heartbeat')
|
logger.debug('........recording heartbeat')
|
||||||
db(sw.worker_name==self.worker_name).update(
|
db(sw.worker_name==self.worker_name).update(
|
||||||
last_heartbeat = now)
|
last_heartbeat = now)
|
||||||
|
|
||||||
elif mybackedstatus.status == TERMINATE:
|
elif mybackedstatus.status == TERMINATE:
|
||||||
self.worker_status = TERMINATE, self.worker_status[1]
|
self.worker_status = TERMINATE, self.worker_status[1]
|
||||||
logging.debug("Waiting to terminate the current task")
|
logger.debug("Waiting to terminate the current task")
|
||||||
self.give_up()
|
self.give_up()
|
||||||
return
|
return
|
||||||
elif mybackedstatus.status == KILL:
|
elif mybackedstatus.status == KILL:
|
||||||
@@ -693,7 +694,7 @@ class Scheduler(MetaScheduler):
|
|||||||
self.die()
|
self.die()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.debug('........recording heartbeat')
|
logger.debug('........recording heartbeat')
|
||||||
db(sw.worker_name==self.worker_name).update(
|
db(sw.worker_name==self.worker_name).update(
|
||||||
last_heartbeat = now, status = ACTIVE)
|
last_heartbeat = now, status = ACTIVE)
|
||||||
self.worker_status = ACTIVE, 1 #re-activating the process
|
self.worker_status = ACTIVE, 1 #re-activating the process
|
||||||
@@ -702,7 +703,7 @@ class Scheduler(MetaScheduler):
|
|||||||
if counter % 5 == 0:
|
if counter % 5 == 0:
|
||||||
try:
|
try:
|
||||||
# delete inactive workers
|
# delete inactive workers
|
||||||
logging.debug(' freeing workers that have not sent heartbeat')
|
logger.debug(' freeing workers that have not sent heartbeat')
|
||||||
inactive_workers = db(
|
inactive_workers = db(
|
||||||
((sw.last_heartbeat<expiration) & (sw.status == ACTIVE)) |
|
((sw.last_heartbeat<expiration) & (sw.status == ACTIVE)) |
|
||||||
((sw.last_heartbeat<departure) & (sw.status != ACTIVE))
|
((sw.last_heartbeat<departure) & (sw.status != ACTIVE))
|
||||||
@@ -730,11 +731,11 @@ class Scheduler(MetaScheduler):
|
|||||||
if not ticker:
|
if not ticker:
|
||||||
db(sw.worker_name == self.worker_name).update(is_ticker = True)
|
db(sw.worker_name == self.worker_name).update(is_ticker = True)
|
||||||
db(sw.worker_name != self.worker_name).update(is_ticker = False)
|
db(sw.worker_name != self.worker_name).update(is_ticker = False)
|
||||||
logging.info("TICKER: I'm a ticker (%s)" % self.worker_name)
|
logger.info("TICKER: I'm a ticker (%s)" % self.worker_name)
|
||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logging.info("%s is a ticker, I'm a poor worker" % ticker.worker_name)
|
logger.info("%s is a ticker, I'm a poor worker" % ticker.worker_name)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def assign_tasks(self):
|
def assign_tasks(self):
|
||||||
@@ -798,12 +799,61 @@ class Scheduler(MetaScheduler):
|
|||||||
#I didn't report tasks but I'm working nonetheless!!!!
|
#I didn't report tasks but I'm working nonetheless!!!!
|
||||||
if len(tasks) > 0:
|
if len(tasks) > 0:
|
||||||
self.empty_runs = 0
|
self.empty_runs = 0
|
||||||
logging.info('TICKER: workers are %s' % len(all_workers))
|
logger.info('TICKER: workers are %s' % len(all_workers))
|
||||||
logging.info('TICKER: tasks are %s' % len(tasks))
|
logger.info('TICKER: tasks are %s' % len(tasks))
|
||||||
|
|
||||||
def sleep(self):
|
def sleep(self):
|
||||||
time.sleep(self.heartbeat*self.worker_status[1]) # should only sleep until next available task
|
time.sleep(self.heartbeat*self.worker_status[1]) # should only sleep until next available task
|
||||||
|
|
||||||
|
def queue_task(self, function, args=[], vars={}, **kwargs):
|
||||||
|
if hasattr(function, '__name__'):
|
||||||
|
function = function.__name__
|
||||||
|
targs = 'args' in kwargs and kwargs.pop('args') or dumps(args)
|
||||||
|
tvars = 'vars' in kwargs and kwargs.pop('vars') or dumps(vars)
|
||||||
|
tuuid = 'uuid' in kwargs and kwargs.pop('uuid') or web2py_uuid()
|
||||||
|
tname = 'task_name' in kwargs and kwargs.pop('task_name') or function
|
||||||
|
rtn = self.db.scheduler_task.validate_and_insert(
|
||||||
|
function_name=function,
|
||||||
|
task_name=tname,
|
||||||
|
args=targs,
|
||||||
|
vars=tvars,
|
||||||
|
uuid=tuuid,
|
||||||
|
**kwargs)
|
||||||
|
if not rtn.errors:
|
||||||
|
rtn.uuid = tuuid
|
||||||
|
else:
|
||||||
|
rtn.uuid = None
|
||||||
|
return rtn
|
||||||
|
|
||||||
|
def task_status(self, ref, output=False):
|
||||||
|
from gluon.dal import Query
|
||||||
|
sr, st = self.db.scheduler_run, self.db.scheduler_task
|
||||||
|
if isinstance(ref, int):
|
||||||
|
q = st.id == ref
|
||||||
|
elif isinstance(ref, str):
|
||||||
|
q = st.uuid == ref
|
||||||
|
elif isinstance(ref, Query):
|
||||||
|
q = ref
|
||||||
|
else:
|
||||||
|
raise SyntaxError, "You can retrieve results only by id, uuid or Query"
|
||||||
|
fields = st.ALL
|
||||||
|
left = False
|
||||||
|
orderby = ~st.id
|
||||||
|
if output:
|
||||||
|
fields = st.ALL, sr.ALL
|
||||||
|
left = sr.on(sr.scheduler_task == st.id)
|
||||||
|
orderby = ~st.id|~sr.id
|
||||||
|
row = self.db(q).select(
|
||||||
|
*fields,
|
||||||
|
orderby=orderby,
|
||||||
|
left=left,
|
||||||
|
limitby=(0,1)
|
||||||
|
).first()
|
||||||
|
if output:
|
||||||
|
row.result = row.scheduler_run.result and \
|
||||||
|
loads(row.scheduler_run.result, object_hook=_decode_dict) or None
|
||||||
|
return row
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
allows to run worker without python web2py.py .... by simply python this.py
|
allows to run worker without python web2py.py .... by simply python this.py
|
||||||
@@ -860,7 +910,7 @@ def main():
|
|||||||
tasks = {}
|
tasks = {}
|
||||||
group_names = [x.strip() for x in options.group_names.split(',')]
|
group_names = [x.strip() for x in options.group_names.split(',')]
|
||||||
|
|
||||||
logging.getLogger().setLevel(options.logger_level)
|
logger.getLogger().setLevel(options.logger_level)
|
||||||
|
|
||||||
print 'groups for this worker: '+', '.join(group_names)
|
print 'groups for this worker: '+', '.join(group_names)
|
||||||
print 'connecting to database in folder: ' + options.db_folder or './'
|
print 'connecting to database in folder: ' + options.db_folder or './'
|
||||||
|
|||||||
Reference in New Issue
Block a user