[FIX] hw_drivers: Lost IoT events
Events coming from the IoT Box were lost in two cases: 1. Create a listener for device 1 2. Send an action to device 1 --> If the action arrives before the listener the event is never sent to the DB 1. Setup up two listeners for devices 1 & 2 2. After a few seconds, send two consecutive actions to devices 1 & 2 --> Everytime a longpolling request arrives, a new threading.Event object is created. The first action sets the event, then, before the new longpolling request arrives, the second action sets the same event, which is overwritten once the new longpolling request arrives. We now maintain a list of events, and when a longpolling request arrives on the IoT Box, we make sure that all events that occured in the last 5 seconds were received by the DB. If no events were pending, we wait 50 seconds to check if a new one pops up. Taskid: 2320958 X-original-commit: e3260712ce96a8d81bf807574c334d92c37c6ae4
This commit is contained in:
@@ -6,6 +6,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from odoo import http, tools
|
||||
from odoo.http import send_file
|
||||
@@ -48,6 +49,18 @@ class DriverController(http.Controller):
|
||||
listener is a dict in witch there are a sessions_id and a dict of device_identifier to listen
|
||||
"""
|
||||
req = event_manager.add_request(listener)
|
||||
|
||||
# Search for previous events and remove events older than 5 seconds
|
||||
oldest_time = time.time() - 5
|
||||
for event in list(event_manager.events):
|
||||
if event['time'] < oldest_time:
|
||||
del event_manager.events[0]
|
||||
continue
|
||||
if event['device_identifier'] in listener['devices'] and event['time'] > listener['last_event']:
|
||||
event['session_id'] = req['session_id']
|
||||
return event
|
||||
|
||||
# Wait for new event
|
||||
if req['event'].wait(50):
|
||||
req['event'].clear()
|
||||
req['result']['session_id'] = req['session_id']
|
||||
|
||||
@@ -7,6 +7,7 @@ import time
|
||||
|
||||
class EventManager(object):
|
||||
def __init__(self):
|
||||
self.events = []
|
||||
self.sessions = {}
|
||||
|
||||
def _delete_expired_sessions(self, max_time=70):
|
||||
@@ -37,10 +38,15 @@ class EventManager(object):
|
||||
return self.sessions[listener['session_id']]
|
||||
|
||||
def device_changed(self, device):
|
||||
event = {
|
||||
**device.data,
|
||||
'device_identifier': device.device_identifier,
|
||||
'time': time.time(),
|
||||
}
|
||||
self.events.append(event)
|
||||
for session in self.sessions:
|
||||
if device.device_identifier in self.sessions[session]['devices']:
|
||||
self.sessions[session]['result'] = device.data
|
||||
self.sessions[session]['result']['device_identifier'] = device.device_identifier
|
||||
if device.device_identifier in self.sessions[session]['devices'] and not self.sessions[session]['event'].isSet():
|
||||
self.sessions[session]['result'] = event
|
||||
self.sessions[session]['event'].set()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user