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)
def call_bus(self, message, timeout=None, silent=False): self.ensure_one() agent = self if not timeout: timeout = agent.bus_timeout channel = 'remote_agent/{}'.format(self.agent_uid) reply_channel = '{}/{}'.format(channel, uuid.uuid4().hex) message.update({'reply_channel': reply_channel, 'timestamp': time.time(), 'token': agent.sudo().token}) # Commit sending message in separate transaction so that we could get an reply. with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: env = api.Environment(new_cr, self.env.uid, self.env.context) env['bus.bus'].sendone(channel, message) new_cr.commit() # Poll is done is separate transaction in bus.bus so we don't do it. if dispatch: # Gevent instance agent_reply = dispatch.poll(self.env.cr.dbname, [reply_channel], last=0, timeout=timeout) else: # Cron instance started = datetime.utcnow() to_end = started + timedelta(seconds=timeout) agent_reply = None while datetime.now() < to_end: with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: env = api.Environment(new_cr, self.env.uid, self.env.context) rec = env['bus.bus'].sudo().search( [('create_date', '>=', started.strftime( '%Y-%m-%d %H:%M:%S')), ('channel', '=', '"{}"'.format(reply_channel))]) if not rec: time.sleep(0.25) else: logger.debug('Got reply within {} seconds'.format( (datetime.now() - started).total_seconds())) agent_reply = [{'message': json.loads(rec[0].message)}] break if agent_reply: # Update agent state self.sudo().update_state( self.agent_uid, state='online', safe=True, note='{} reply'.format(message['message'])) # Convert result message to dict reply_message = agent_reply[0]['message'] if type(reply_message) != dict: json.loads(reply_message) return reply_message # No reply recieved else: self.sudo().update_state( self.agent_uid, state='offline', safe=True, note='{} not replied'.format(message['message'])) return {}
def send_bus_message(self, request, response_expected, **kwargs): channel = '{}/{}'.format(CHANNEL_PREFIX, self.agent.system_name) self.message['request'] = request reply_channel = '{}/{}'.format(channel, uuid.uuid4().hex) if response_expected: # Add reply channel self.message['reply_channel'] = reply_channel with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: env = api.Environment(new_cr, self.env.uid, self.env.context) env['bus.bus'].sendone(channel, json.dumps(self.message)) new_cr.commit() # Request or notification? if not response_expected: # Notification return JsonRpcResponse('') # Request, wait for response. agent_reply = None # Poll is done in a separate transaction so we don't do it. if dispatch: # Gevent instance agent_reply = dispatch.poll(self.env.cr.dbname, [reply_channel], last=0, timeout=self.agent.bus_timeout) else: # Cron instance started = datetime.utcnow() to_end = started + timedelta(seconds=self.agent.bus_timeout) agent_reply = None while datetime.now() < to_end: with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: env = api.Environment( new_cr, self.env.uid, self.env.context) rec = env['bus.bus'].sudo().search( [('create_date', '>=', started.strftime( '%Y-%m-%d %H:%M:%S')), ('channel', '=', '"{}"'.format(reply_channel))]) if not rec: time.sleep(0.25) else: logger.debug( 'Got reply within %s seconds', (datetime.now() - started).total_seconds()), agent_reply = [{'message': json.loads(rec[0].message)}] break if agent_reply: # Update agent state self.update_state('online', '{} reply'.format(self.message['command'])) # Convert result message to dict return JsonRpcResponse(agent_reply[0]['message']) # No reply recieved else: self.update_state( 'offline', '{} not replied'.format(str(request))) raise AgentError('Offline')
def _poll(self, dbname, channels, last, options): # referrer_url = request.httprequest.headers.get('Referer', '') if request.session.uid and 'bus_inactivity' in options: request.env['bus.presence'].update(options.get('bus_inactivity'), options.get('is_webrtc')) request.cr.close() request._cr = None return dispatch.poll(dbname, channels, last, options)
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( inactivity_period=options.get('bus_inactivity'), identity_field='user_id', identity_value=request.session.uid) request.cr.close() request._cr = None return dispatch.poll(dbname, channels, last, options)
def bus_call(self, params, timeout=POLL_TIMEOUT, silent=False): self.ensure_one() channel = 'asterisk_agent/{}'.format(self.uid) reply_channel = '{}/{}'.format(channel, uuid.uuid4().hex) params.update({'reply_channel': reply_channel}) # Commit sending message in separate transaction so that we could get an reply. with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: env = api.Environment(new_cr, self.env.uid, self.env.context) env['bus.bus'].sendone(channel, json.dumps(params)) new_cr.commit() # Poll is done is separate transaction in bus.bus so we don't do it. if dispatch: # Gevent instance agent_reply = dispatch.poll(self.env.cr.dbname, [reply_channel], last=0, timeout=timeout) else: # Cron instance odoo_started = fields.Datetime.now() started = datetime.now() to_end = started + timedelta(seconds=timeout) agent_reply = None while datetime.now() < to_end: with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: env = api.Environment(new_cr, self.env.uid, self.env.context) rec = env['bus.bus'].sudo().search([ ('create_date', '>=', odoo_started), ('channel', '=', '"{}"'.format(reply_channel)) ]) if not rec: time.sleep(0.2) else: logger.debug('Got reply within {} seconds'.format( (datetime.now() - started).total_seconds())) agent_reply = [{ 'message': json.loads(rec[0].message) if rec else {} }] break if agent_reply: reply_msg = agent_reply[0]['message'] if \ type(agent_reply[0]['message']) in [dict, list] else \ json.loads(agent_reply[0]['message']) self.sudo().last_ping = fields.Datetime.now() return reply_msg else: self.state = 'offline' if not silent: self.env.user.ast_notify_warning( _('No reply from Agent, server {}!').format(self.name)) return {}
def _poll(self, dbname, channels, last, options): channels = list(channels) # do not alter original list channels.append('broadcast') # update the user presence if request.session.uid and 'bus_inactivity' in options: request.env['bus.presence'].update( inactivity_period=options.get('bus_inactivity'), identity_field='user_id', identity_value=request.session.uid) request.env.cr.close() return dispatch.poll(dbname, channels, last, options)