35
38
def __init__(self, app):
37
40
self.address = (config['xmlrpc_interface'] or '0.0.0.0', config['xmlrpc_port'])
38
self.long_polling_address = (config['xmlrpc_interface'] or '0.0.0.0', config['longpolling_port'])
39
41
self.population = config['workers']
40
42
self.timeout = config['limit_time_real']
41
43
self.limit_request = config['limit_request']
94
def long_polling_spawn(self):
95
nargs = stripped_sys_argv('--pidfile')
97
cmd = os.path.join(os.path.dirname(cmd), "openerp-long-polling")
99
popen = subprocess.Popen(nargs)
100
self.long_polling_pid = popen.pid
92
102
def worker_pop(self, pid):
93
103
if pid in self.workers:
94
104
_logger.debug("Worker (%s) unregistered",pid)
143
153
self.worker_spawn(WorkerHTTP, self.workers_http)
144
154
while len(self.workers_cron) < config['max_cron_threads']:
145
155
self.worker_spawn(WorkerCron, self.workers_cron)
146
while len(self.workers_longpolling) < 1:
147
self.worker_spawn(WorkerLongPolling, self.workers_longpolling)
156
if not self.long_polling_pid:
157
self.long_polling_spawn()
183
193
self.socket.setblocking(0)
184
194
self.socket.bind(self.address)
185
195
self.socket.listen(8*self.population)
186
# long polling socket
187
self.long_polling_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
188
self.long_polling_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
189
self.long_polling_socket.setblocking(0)
190
self.long_polling_socket.bind(self.long_polling_address)
191
self.long_polling_socket.listen(8)
193
197
def stop(self, graceful=True):
198
if self.long_polling_pid is not None:
199
self.worker_kill(self.long_polling_pid, signal.SIGTERM)
200
self.long_polling_pid = None
195
202
_logger.info("Stopping gracefully")
196
203
limit = time.time() + self.timeout
355
362
Worker.start(self)
356
self.multi.long_polling_socket.close()
357
363
self.server = WorkerBaseWSGIServer(self.multi.app)
359
class WorkerLongPolling(Worker):
360
""" Long polling workers """
361
def __init__(self, multi):
362
super(WorkerLongPolling, self).__init__(multi)
363
# Disable the watchdog feature for this kind of worker.
364
self.watchdog_timeout = None
366
def watch_parent(self):
369
if self.ppid != os.getppid():
370
_logger.info("WorkerLongPolling (%s) Parent changed", self.pid)
371
os.kill(os.getpid(), signal.SIGTERM)
373
gevent.sleep(self.multi.beat)
376
openerp.evented = True
377
_logger.info('Using gevent mode')
379
gevent.monkey.patch_all()
380
import gevent_psycopg2
381
gevent_psycopg2.monkey_patch()
382
from openerp.modules.registry import RegistryManager
383
from gevent.coros import RLock
384
RegistryManager.registries_lock = RLock()
387
self.multi.socket.close()
390
watcher = gevent.spawn(self.watch_parent)
392
log = _logger.getChild(self.__class__.__name__)
393
log.write = lambda msg: log.info(msg.strip())
395
from gevent.wsgi import WSGIServer
396
self.server = WSGIServer(self.multi.long_polling_socket, self.multi.app, log=log)
397
self.server.serve_forever()
399
365
class WorkerBaseWSGIServer(werkzeug.serving.BaseWSGIServer):
400
366
""" werkzeug WSGI Server patched to allow using an external listen socket