Browse Source

redefined the API to avoid GC issues during the destruction of the AMAN and its children

Sven Czarnian 3 years ago
parent
commit
484be00e8c
4 changed files with 59 additions and 19 deletions
  1. 18 9
      aman/AMAN.py
  2. 23 6
      aman/com/Euroscope.py
  3. 10 2
      aman/com/Weather.py
  4. 8 2
      aman/sys/Worker.py

+ 18 - 9
aman/AMAN.py

@@ -34,6 +34,10 @@ class AMAN:
         self.workers = []
         self.inbounds = {}
 
+    def __del__(self):
+        self.release()
+
+    def aquire(self):
         configPath = AMAN.findConfigPath()
 
         # read all system relevant configuration files
@@ -48,7 +52,8 @@ class AMAN:
         else:
             print('Parsed PerformanceData.ini. Extracted ' + str(len(self.aircraftPerformance.aircrafts)) + ' aircrafts')
 
-        self.weather = Weather(self.systemConfig.Weather)
+        self.weather = Weather()
+        self.weather.acquire(self.systemConfig.Weather)
 
         # find the airport configurations and create the workers
         airportsPath = os.path.join(os.path.join(configPath, 'airports'), '*.ini')
@@ -59,24 +64,28 @@ class AMAN:
             airportConfig = Airport(file, icao)
 
             # initialize the worker thread
-            worker = Worker(icao, airportConfig)
-            worker.start()
+            worker = Worker()
+            worker.acquire(icao, airportConfig)
             self.workers.append(worker)
             print('Starter worker for ' + icao)
 
         # create the EuroScope receiver
-        self.receiver = Euroscope(configPath, self.systemConfig.Server, self)
+        self.receiver = Euroscope()
+        self.receiver.acquire(configPath, self.systemConfig.Server, self)
 
-    def __del__(self):
+    def release(self):
         if None != self.receiver:
-            del self.receiver
+            self.receiver.release()
         self.receiver = None
+
         if None != self.weather:
-            del self.weather
+            self.weather.release()
         self.weather = None
 
-        for worker in self.workers:
-            worker.stop()
+        if None != self.workers:
+            for worker in self.workers:
+                worker.release()
+        self.workers = None
 
     def updateAircraftReport(self, report : AircraftReport_pb2.AircraftReport):
         # find the correct worker for the inbound

+ 23 - 6
aman/com/Euroscope.py

@@ -53,9 +53,18 @@ class ReceiverThread(Thread):
 
 # @brief Receives and sends messages to EuroScope plugins
 class Euroscope:
+    def __init__(self):
+        self.context = None
+        self.receiverSocket = None
+        self.receiverThread = None
+        self.notificationSocket = None
+
+    def __del__(self):
+        self.release()
+
     # @brief Initializes the ZMQ socket
     # @param[in] config The server configuration
-    def __init__(self, configPath : str, config : Server, aman):
+    def acquire(self, configPath : str, config : Server, aman):
         self.context = zmq.Context()
 
         # find the key directories
@@ -97,8 +106,16 @@ class Euroscope:
         self.notificationSocket.bind('tcp://' + config.Address + ':' + str(config.PortNotification))
         print('Publishing to tcp://' + config.Address + ':' + str(config.PortNotification))
 
-    def __del__(self):
-        self.receiverThread.stopThread()
-        self.receiverThread.join()
-        self.receiverSocket.close()
-        self.notificationSocket.close()
+    def release(self):
+        if None != self.receiverThread:
+            self.receiverThread.stopThread()
+            self.receiverThread.join()
+        self.receiverThread = None
+
+        if None != self.receiverSocket:
+            self.receiverSocket.close()
+        self.receiverSocket = None
+
+        if None != self.notificationSocket:
+            self.notificationSocket.close()
+        self.notificationSocket = None

+ 10 - 2
aman/com/Weather.py

@@ -12,8 +12,15 @@ from aman.com.DwdCrawler import DwdCrawler
 import aman.config.Weather
 
 class Weather(Thread):
-    def __init__(self, config : aman.config.Weather.Weather):
+    def __init__(self):
         Thread.__init__(self)
+
+        self.nextUpdate = None
+        self.lastUpdateTried = None
+        self.stopThread = False
+        self.provider = None
+
+    def acquire(self, config : aman.config.Weather.Weather):
         self.nextUpdate = dt.utcfromtimestamp(int(time.time()))
         self.lastUpdateTried = None
         self.stopThread = False
@@ -27,8 +34,9 @@ class Weather(Thread):
 
         self.start()
 
-    def stop(self):
+    def release(self):
         self.stopThread = True
+        self.join()
 
     def currentClock():
         clock = dt.utcfromtimestamp(int(time.time()))

+ 8 - 2
aman/sys/Worker.py

@@ -6,18 +6,24 @@ import time
 from aman.config.Airport import Airport
 
 class Worker(Thread):
-    def __init__(self, icao : str, configuration : Airport):
+    def __init__(self):
         Thread.__init__(self)
 
+    def __del__(self):
+        self.release()
+
+    def acquire(self, icao : str, configuration : Airport):
         self.stopThread = None
         self.icao = icao
         self.configuration = configuration
         self.arrivalRoutes = configuration.gngData.arrivalRoutes
         self.updateLock = Lock()
         self.reportQueue = {}
+        self.start()
 
-    def stop(self):
+    def release(self):
         self.stopThread = True
+        self.join()
 
     def run(self):
         counter = 0