|
1 | 1 | import logging
|
2 |
| -from typing import Dict, Union |
| 2 | +from typing import Dict |
3 | 3 |
|
4 | 4 | import django.utils.timezone
|
5 | 5 |
|
6 | 6 | from telemetry.models import Driver
|
7 | 7 |
|
8 |
| -from .session import Session |
9 |
| -from .session_rbr import SessionRbr |
10 |
| - |
11 | 8 |
|
12 | 9 | class ActiveDrivers:
|
13 |
| - def __init__(self, debug=False): |
| 10 | + def __init__(self, debug=False, inactive_timeout_seconds=600): |
14 | 11 | self.debug = debug
|
15 |
| - self.sessions: Dict[str, Union[Session, SessionRbr]] = {} |
16 |
| - self.do_clear_sessions = False |
| 12 | + self.inactive_timeout_seconds = inactive_timeout_seconds |
| 13 | + self.topics: Dict[str, dict] = {} # Maps topic to metadata including driver and last_seen |
17 | 14 |
|
18 | 15 | def notify(self, topic, payload, now=None):
|
19 | 16 | now = now or django.utils.timezone.now()
|
20 |
| - if topic not in self.sessions: |
| 17 | + |
| 18 | + if topic not in self.topics: |
21 | 19 | try:
|
22 | 20 | (
|
23 | 21 | prefix,
|
24 |
| - driver, |
| 22 | + driver_name, |
25 | 23 | session_id,
|
26 | 24 | game,
|
27 | 25 | track,
|
28 | 26 | car,
|
29 | 27 | session_type,
|
30 | 28 | ) = topic.split("/")
|
31 | 29 | except ValueError:
|
32 |
| - # ignore invalid session |
| 30 | + # ignore invalid topic |
33 | 31 | return
|
34 | 32 |
|
35 |
| - if game == "Richard Burns Rally": |
36 |
| - session = SessionRbr(topic, start=now) |
37 |
| - else: |
38 |
| - session = Session(topic, start=now) |
39 |
| - |
40 | 33 | try:
|
41 |
| - db_driver, created = Driver.objects.get_or_create(name=driver) |
42 |
| - session.driver = db_driver |
43 |
| - session.session_id = session_id |
44 |
| - logging.debug(f"New session: {topic}") |
45 |
| - session.game_name = game |
46 |
| - session.track = track |
47 |
| - session.car = car |
48 |
| - session.car_class = payload.get("CarClass", "") |
49 |
| - session.session_type = session_type |
50 |
| - self.sessions[topic] = session |
| 34 | + db_driver, created = Driver.objects.get_or_create(name=driver_name) |
| 35 | + self.topics[topic] = {"driver": db_driver, "last_seen": now, "session_id": session_id, "game": game, "track": track, "car": car, "car_class": payload.get("CarClass", ""), "session_type": session_type} |
| 36 | + logging.debug(f"New topic: {topic}") |
51 | 37 | except Exception as e:
|
52 |
| - logging.error(f"Error creating driver {driver} - {e}") |
| 38 | + logging.error(f"Error creating driver {driver_name} - {e}") |
53 | 39 | return
|
54 |
| - |
55 |
| - session = self.sessions[topic] |
56 |
| - session.end = now |
57 |
| - if self.do_clear_sessions: |
| 40 | + # clear inactive topics every time a new topic is added |
58 | 41 | self.clear_sessions(now)
|
| 42 | + else: |
| 43 | + self.topics[topic]["last_seen"] = now |
59 | 44 |
|
60 |
| - # TODO: clear sessions every now and then |
61 | 45 | def clear_sessions(self, now):
|
62 |
| - """Clear inactive telemetry sessions. |
| 46 | + """Clear inactive topics. |
63 | 47 |
|
64 |
| - Loops through all sessions and deletes: |
65 |
| - - Any session inactive for more than 10 minutes |
66 |
| - - Any lap marked for deletion |
| 48 | + Removes any topic that hasn't received updates for longer than inactive_timeout_seconds |
67 | 49 |
|
68 | 50 | Args:
|
69 | 51 | now (datetime): The current datetime
|
70 |
| -
|
71 | 52 | """
|
| 53 | + delete_topics = [] |
| 54 | + for topic, metadata in self.topics.items(): |
| 55 | + if (now - metadata["last_seen"]).seconds > self.inactive_timeout_seconds: |
| 56 | + delete_topics.append(topic) |
72 | 57 |
|
73 |
| - delete_sessions = [] |
74 |
| - for topic, session in self.sessions.items(): |
75 |
| - # Delete session without updates for 10 minutes |
76 |
| - if (now - session.end).seconds > 600: |
77 |
| - delete_sessions.append(topic) |
| 58 | + for topic in delete_topics: |
| 59 | + del self.topics[topic] |
| 60 | + logging.debug(f"{topic}\n\t deleting inactive topic") |
78 | 61 |
|
79 |
| - # Delete all inactive sessions |
80 |
| - for topic in delete_sessions: |
81 |
| - del self.sessions[topic] |
82 |
| - logging.debug(f"{topic}\n\t deleting inactive session") |
| 62 | + def drivers(self): |
| 63 | + """Return set of all active drivers""" |
| 64 | + return {metadata["driver"] for metadata in self.topics.values()} |
0 commit comments