[IMP] cron: added signal handler for Ctrl-C.

bzr revid: vmt@openerp.com-20120328115109-9offjmjqzq6w9k6q
This commit is contained in:
Vo Minh Thu
2012-03-28 13:51:09 +02:00
parent 1b0bfd1044
commit 18de40b351
2 changed files with 59 additions and 2 deletions
+44
View File
@@ -9,14 +9,58 @@ OpenERP server but depending on deployment needs, independent worker processes
can be used.
"""
import logging
import os
import signal
import sys
import openerp
# Also use the `openerp` logger for the main script.
_logger = logging.getLogger('openerp')
# Variable keeping track of the number of calls to the signal handler defined
# below. This variable is monitored by ``quit_on_signals()``.
quit_signals_received = 0
# TODO copy/pasted from openerp-server
def signal_handler(sig, frame):
""" Signal handler: exit ungracefully on the second handled signal.
:param sig: the signal number
:param frame: the interrupted stack frame or None
"""
global quit_signals_received
quit_signals_received += 1
import openerp.addons.base
openerp.addons.base.ir.ir_cron.quit_signal_received = True
if quit_signals_received == 1 and openerp.addons.base.ir.ir_cron.job_in_progress:
_logger.info("Waiting for the current job to complete.")
print "Waiting for the current job to complete."
print "Hit Ctrl-C again to force shutdown."
if quit_signals_received > 1:
# logging.shutdown was already called at this point.
sys.stderr.write("Forced shutdown.\n")
os._exit(0)
# TODO copy/pasted from openerp-server
def setup_signal_handlers():
""" Register the signal handler defined above. """
SIGNALS = map(lambda x: getattr(signal, "SIG%s" % x), "INT TERM".split())
if os.name == 'posix':
map(lambda sig: signal.signal(sig, signal_handler), SIGNALS)
elif os.name == 'nt':
import win32api
win32api.SetConsoleCtrlHandler(lambda sig: signal_handler(sig, None), 1)
if __name__ == '__main__':
setup_signal_handlers()
openerp.modules.module.initialize_sys_path()
openerp.modules.loading.open_openerp_namespace()
openerp.tools.config['log_handler'] = ['openerp.addons.base.ir.ir_cron:DEBUG']
openerp.netsvc.init_logger()
import openerp.addons.base
print "OpenERP cron jobs worker. Hit Ctrl-C to exit."
openerp.addons.base.ir.ir_cron.ir_cron._run(['xx'])
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+15 -2
View File
@@ -38,6 +38,14 @@ from tools.translate import _
_logger = logging.getLogger(__name__)
# This variable can be set by a signal handler to stop the infinite loop in
# ir_cron._run()
quit_signal_received = False
# This variable can be checked to know if ir_cron._run() is processing a job or
# sleeping.
job_in_progress = True
def str2tuple(s):
return eval('tuple(%s)' % (s or ''))
@@ -231,17 +239,22 @@ class ir_cron(osv.osv):
@classmethod
def _run(cls, db_names):
while True:
global quit_signal_received
while not quit_signal_received:
t1 = time.time()
for db_name in db_names:
while(cls._acquire_job(db_name)):
pass
if quit_signal_received:
return
t2 = time.time()
t = t2 - t1
global job_in_progress
if t > 60:
_logger.warning('Cron worker: processing all jobs took more than 1 minute to complete (%ss.).', int(t))
else:
job_in_progress = False
time.sleep(60 - t)
job_in_progress = True
def _try_lock(self, cr, uid, ids, context=None):
"""Try to grab a dummy exclusive write-lock to the rows with the given ids,