diff --git a/owrx/map.py b/owrx/map.py index 9dc5c48..081a691 100644 --- a/owrx/map.py +++ b/owrx/map.py @@ -25,13 +25,23 @@ class Map(object): def __init__(self): self.clients = [] self.positions = {} + self.positionsLock = threading.Lock() def removeLoop(): + loops = 0 while True: try: self.removeOldPositions() except Exception: logger.exception("error while removing old map positions") + loops += 1 + # rebuild the positions dictionary every once in a while, it consumes lots of memory otherwise + if loops == 60: + try: + self.rebuildPositions() + except Exception: + logger.exception("error while rebuilding positions") + loops = 0 time.sleep(60) threading.Thread(target=removeLoop, daemon=True).start() @@ -64,7 +74,8 @@ class Map(object): def updateLocation(self, callsign, loc: Location, mode: str, band: Band = None): ts = datetime.now() - self.positions[callsign] = {"location": loc, "updated": ts, "mode": mode, "band": band} + with self.positionsLock: + self.positions[callsign] = {"location": loc, "updated": ts, "mode": mode, "band": band} self.broadcast( [ { @@ -80,13 +91,15 @@ class Map(object): def touchLocation(self, callsign): # not implemented on the client side yet, so do not use! ts = datetime.now() - if callsign in self.positions: - self.positions[callsign]["updated"] = ts + with self.positionsLock: + if callsign in self.positions: + self.positions[callsign]["updated"] = ts self.broadcast([{"callsign": callsign, "lastseen": ts.timestamp() * 1000}]) def removeLocation(self, callsign): - self.positions.pop(callsign, None) - # TODO broadcast removal to clients + with self.positionsLock: + del self.positions[callsign] + # TODO broadcast removal to clients def removeOldPositions(self): pm = PropertyManager.getSharedInstance() @@ -97,6 +110,11 @@ class Map(object): for callsign in to_be_removed: self.removeLocation(callsign) + def rebuildPositions(self): + with self.positionsLock: + p = {key: value for key, value in self.positions.items()} + self.positions = p + class LatLngLocation(Location): def __init__(self, lat: float, lon: float):