Commit5d1b323. re-enabled the user presence updates and notifications. Unfortunately, it showed poor performance due to the high frequency of bus notifications triggered on our instance (~600k users). In this rev., we don't trigger notifications on presence changes anymore, but we rather send the presence of users we have a DM open with, at the end of each poll period. For performance reasons, we ensure not to do that more than once every 30 seconds. We also refined the detection of the 'away' status client side. 'Last presence' timestamps are stored in the local storage, and the current inactivity period is sent at each poll. Those presence timestamps now rely on browser activity detection (click, keypress... events) rather than on the focus on Odoo tabs. Finally, we removed the no more necessary cron introduced in5d1b323.
40 lines
1.7 KiB
Python
40 lines
1.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
import openerp
|
|
from openerp.http import request
|
|
from openerp.addons.bus.models.bus import dispatch
|
|
|
|
|
|
class BusController(openerp.http.Controller):
|
|
""" Examples:
|
|
openerp.jsonRpc('/longpolling/poll','call',{"channels":["c1"],last:0}).then(function(r){console.log(r)});
|
|
openerp.jsonRpc('/longpolling/send','call',{"channel":"c1","message":"m1"});
|
|
openerp.jsonRpc('/longpolling/send','call',{"channel":"c2","message":"m2"});
|
|
"""
|
|
|
|
@openerp.http.route('/longpolling/send', type="json", auth="public")
|
|
def send(self, channel, message):
|
|
if not isinstance(channel, basestring):
|
|
raise Exception("bus.Bus only string channels are allowed.")
|
|
return request.env['bus.bus'].sendone(channel, message)
|
|
|
|
# override to add channels
|
|
def _poll(self, dbname, channels, last, options):
|
|
# update the user presence
|
|
if request.session.uid and 'bus_inactivity' in options:
|
|
request.env['bus.presence'].update(options.get('bus_inactivity'))
|
|
request.cr.close()
|
|
request._cr = None
|
|
return dispatch.poll(dbname, channels, last, options)
|
|
|
|
@openerp.http.route('/longpolling/poll', type="json", auth="public")
|
|
def poll(self, channels, last, options=None):
|
|
if options is None:
|
|
options = {}
|
|
if not dispatch:
|
|
raise Exception("bus.Bus unavailable")
|
|
if [c for c in channels if not isinstance(c, basestring)]:
|
|
raise Exception("bus.Bus only string channels are allowed.")
|
|
if request.registry.in_test_mode():
|
|
raise openerp.exceptions.UserError("bus.Bus not available in test mode")
|
|
return self._poll(request.db, channels, last, options)
|