1414from odoo import api , fields , models
1515from odoo .service .server import CommonServer
1616from odoo .tools import json_default , SQL
17- from odoo .tools .constants import GC_UNLINK_LIMIT
1817from odoo .tools .misc import OrderedSet
1918
2019_logger = logging .getLogger (__name__ )
@@ -41,12 +40,37 @@ def get_notify_payload_max_length(default=8000):
4140NOTIFY_PAYLOAD_MAX_LENGTH = get_notify_payload_max_length ()
4241
4342
43+ def fetch_bus_notifications (cr , channels , last = 0 , ignore_ids = None ):
44+ """Fetch notifications from the bus table.
45+
46+ :param cr: Database cursor.
47+ :param channels: List of channels for which notifications should be fetched.
48+ May contain channel names, model instances, or (model, string) tuples.
49+ :param last: The ID of the last fetched notification. Defaults to 0.
50+ :param ignore_ids: IDs to exclude.
51+ :return: List of notifications.
52+
53+ """
54+ conditions = [
55+ SQL ("channel IN %s" , tuple (json_dump (channel_with_db (cr .dbname , c )) for c in channels )),
56+ SQL ("create_date > %s" , fields .Datetime .now () - datetime .timedelta (seconds = TIMEOUT ))
57+ if last == 0
58+ else SQL ("id > %s" , last ),
59+ ]
60+ if ignore_ids :
61+ conditions .append (SQL ("id NOT IN %s" , tuple (ignore_ids )))
62+ where = SQL (" AND " ).join (conditions )
63+ cr .execute (SQL ("SELECT id, message FROM bus_bus WHERE %s ORDER BY id" , where ))
64+ return [{"id" : r [0 ], "message" : json .loads (r [1 ])} for r in cr .fetchall ()]
65+
66+
4467# ---------------------------------------------------------
4568# Bus
4669# ---------------------------------------------------------
4770def json_dump (v ):
4871 return json .dumps (v , separators = (',' , ':' ), default = json_default )
4972
73+
5074def hashable (key ):
5175 if isinstance (key , list ):
5276 key = tuple (key )
@@ -164,25 +188,7 @@ def notify():
164188
165189 @api .model
166190 def _poll (self , channels , last = 0 , ignore_ids = None ):
167- # first poll return the notification in the 'buffer'
168- if last == 0 :
169- timeout_ago = fields .Datetime .now () - datetime .timedelta (seconds = TIMEOUT )
170- domain = [('create_date' , '>' , timeout_ago )]
171- else : # else returns the unread notifications
172- domain = [('id' , '>' , last )]
173- if ignore_ids :
174- domain .append (("id" , "not in" , ignore_ids ))
175- channels = [json_dump (channel_with_db (self .env .cr .dbname , c )) for c in channels ]
176- domain .append (('channel' , 'in' , channels ))
177- notifications = self .sudo ().search_read (domain , ["message" ])
178- # list of notification to return
179- result = []
180- for notif in notifications :
181- result .append ({
182- 'id' : notif ['id' ],
183- 'message' : json .loads (notif ['message' ]),
184- })
185- return result
191+ return fetch_bus_notifications (self .env .cr , channels , last , ignore_ids )
186192
187193 def _bus_last_id (self ):
188194 last = self .env ['bus.bus' ].search ([], order = 'id desc' , limit = 1 )
@@ -193,12 +199,6 @@ def _bus_last_id(self):
193199# Dispatcher
194200# ---------------------------------------------------------
195201
196- class BusSubscription :
197- def __init__ (self , channels , last ):
198- self .last_notification_id = last
199- self .channels = channels
200-
201-
202202class ImDispatch (threading .Thread ):
203203 def __init__ (self ):
204204 super ().__init__ (daemon = True , name = f'{ __name__ } .Bus' )
0 commit comments