2 # -*- coding: utf-8 -*-
5 OpenERP cron jobs worker
7 This script executes OpenERP cron jobs. Normally, cron jobs are handled by the
8 OpenERP server but depending on deployment needs, independent worker processes
9 can be used. This is especially the case when the server is run via Gunicorn.
11 OpenERP cron jobs worker re-uses openerp-server command-line options but does
12 not honor all of them.
14 Meaningful options include:
16 -d, --database comma-separated list of databases to monitor for cron jobs
17 processing. If left empty, the worker monitors all databases
18 (given by `psql -ls`).
20 --addons-path as ususal.
23 --virtual-memory-limit
24 --virtual-memory-reset Those three options have the same meaning the for
25 the server with Gunicorn. The only catch is: To
26 not enable rlimits by default, those options are
27 honored only when --cpu-time-limte is different than
28 60 (its default value).
38 # Also use the `openerp` logger for the main script.
39 _logger = logging.getLogger('openerp')
41 # Variable keeping track of the number of calls to the signal handler defined
42 # below. This variable is monitored by ``quit_on_signals()``.
43 quit_signals_received = 0
45 # TODO copy/pasted from openerp-server
46 def signal_handler(sig, frame):
47 """ Signal handler: exit ungracefully on the second handled signal.
49 :param sig: the signal number
50 :param frame: the interrupted stack frame or None
52 global quit_signals_received
53 quit_signals_received += 1
54 import openerp.addons.base
55 openerp.addons.base.ir.ir_cron.quit_signal_received = True
56 if quit_signals_received == 1 and openerp.addons.base.ir.ir_cron.job_in_progress:
57 _logger.info("Waiting for the current job to complete.")
58 print "Waiting for the current job to complete."
59 print "Hit Ctrl-C again to force shutdown."
60 if quit_signals_received > 1:
61 # logging.shutdown was already called at this point.
62 sys.stderr.write("Forced shutdown.\n")
65 # TODO copy/pasted from openerp-server
66 def setup_signal_handlers():
67 """ Register the signal handler defined above. """
68 SIGNALS = map(lambda x: getattr(signal, "SIG%s" % x), "INT TERM".split())
69 if os.name == 'posix':
70 map(lambda sig: signal.signal(sig, signal_handler), SIGNALS)
73 win32api.SetConsoleCtrlHandler(lambda sig: signal_handler(sig, None), 1)
77 p1 = subprocess.Popen(["psql", "-lAt"], stdout=subprocess.PIPE)
78 p2 = subprocess.Popen(["cut", "-f", "1", "-d", "|"], stdin=p1.stdout, stdout=subprocess.PIPE)
79 p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
80 output = p2.communicate()[0]
81 databases = output.splitlines()
82 # TODO filter out non-OpenERP databases
83 databases = [d for d in databases if d not in ['template0', 'template1', 'postgres']]
84 databases = [d for d in databases if not d.startswith('postgres')]
87 if __name__ == '__main__':
88 os.environ['TZ'] = 'UTC'
89 openerp.tools.config.parse_config(sys.argv[1:])
90 config = openerp.tools.config
91 if config['log_handler'] == [':INFO']:
92 # Replace the default value, which is suitable for openerp-server.
93 config['log_handler'].append('openerp.addons.base.ir.ir_cron:DEBUG')
94 setup_signal_handlers()
95 openerp.modules.module.initialize_sys_path()
96 openerp.modules.loading.open_openerp_namespace()
97 openerp.netsvc.init_logger()
98 openerp.cron.enable_schedule_wakeup = False
99 openerp.multi_process = True # enable multi-process signaling
100 import openerp.addons.base
101 print "OpenERP cron jobs worker. Hit Ctrl-C to exit."
102 print "Documentation is available at the top of the `opener-cron-worker` file."
103 if config['db_name']:
104 db_names = config['db_name'].split(',')
105 print "Monitoring %s databases." % len(db_names)
107 db_names = list_databases
108 print "Monitored databases are auto-discovered."
109 openerp.addons.base.ir.ir_cron.ir_cron._run(db_names)
111 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: