You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.5 KiB
77 lines
2.5 KiB
# Copyright 2019 Trobz <https://trobz.com>
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
import os
|
|
import json
|
|
import logging
|
|
import select
|
|
|
|
import psycopg2
|
|
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
|
|
|
import odoo
|
|
from odoo.tools import config
|
|
|
|
from odoo.addons.bus.models.bus import hashable, TIMEOUT
|
|
import odoo.addons.bus.models.bus
|
|
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _connection_info_for(db_name):
|
|
db_or_uri, connection_info = odoo.sql_db.connection_info_for(db_name)
|
|
|
|
for p in ('host', 'port'):
|
|
cfg = (os.environ.get('ODOO_IMDISPATCHER_DB_%s' % p.upper()) or
|
|
config.get('imdispatcher_db_' + p))
|
|
|
|
if cfg:
|
|
connection_info[p] = cfg
|
|
|
|
return connection_info
|
|
|
|
|
|
class ImDispatch(odoo.addons.bus.models.bus.ImDispatch):
|
|
|
|
def loop(self):
|
|
""" Dispatch postgres notifications to the relevant
|
|
polling threads/greenlets """
|
|
connection_info = _connection_info_for('postgres')
|
|
_logger.info("Bus.loop listen imbus on db postgres "
|
|
"(via %(host)s:%(port)s)",
|
|
connection_info)
|
|
conn = psycopg2.connect(**connection_info)
|
|
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
|
|
with conn.cursor() as cr:
|
|
cr.execute("listen imbus")
|
|
conn.commit()
|
|
while True:
|
|
if select.select([conn], [], [], TIMEOUT) == ([], [], []):
|
|
pass
|
|
else:
|
|
conn.poll()
|
|
channels = []
|
|
while conn.notifies:
|
|
channels.extend(json.loads(conn
|
|
.notifies.pop().payload))
|
|
# dispatch to local threads/greenlets
|
|
events = set()
|
|
for channel in channels:
|
|
events.update(self.channels.pop(hashable(channel),
|
|
set()))
|
|
for event in events:
|
|
event.set()
|
|
|
|
|
|
odoo.addons.bus.models.bus.ImDispatch = ImDispatch
|
|
|
|
# we can replace the existing dispatcher because its thread
|
|
# has not been started yet; indeed, since a2ed3d it only starts
|
|
# on first /poll request:
|
|
# https://github.com/odoo/odoo/commit/a2ed3d3d5bdb6025a1ba14ad557a115a86413e65
|
|
|
|
if not odoo.multi_process or odoo.evented:
|
|
dispatch = ImDispatch()
|
|
odoo.addons.bus.models.bus.dispatch = dispatch
|
|
odoo.addons.bus.controllers.main.dispatch = dispatch
|