mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-20 22:37:44 +00:00
104 lines
4.0 KiB
Python
104 lines
4.0 KiB
Python
import logging
|
|
import threading
|
|
import time
|
|
|
|
from core.config import config, create_provider_from_config
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class DataProviders:
|
|
"""Global object for storing data providers."""
|
|
|
|
def __init__(self):
|
|
self.spot_providers = []
|
|
self.alert_providers = []
|
|
self.solar_condition_providers = []
|
|
self.static_data_providers = []
|
|
self.sig_ref_data_providers = []
|
|
self.callsign_data_providers = []
|
|
self._startup_timers = []
|
|
|
|
def setup(self):
|
|
for entry in config["spot_providers"]:
|
|
self.spot_providers.append(create_provider_from_config("providers.spot", entry))
|
|
for entry in config["alert_providers"]:
|
|
self.alert_providers.append(create_provider_from_config("providers.alert", entry))
|
|
for entry in config.get("solar_condition_providers", []):
|
|
self.solar_condition_providers.append(create_provider_from_config("providers.solarconditions", entry))
|
|
for entry in config.get("static_data_providers", []):
|
|
self.static_data_providers.append(create_provider_from_config("providers.staticdata", entry))
|
|
for entry in config.get("sig_ref_data_providers", []):
|
|
self.sig_ref_data_providers.append(create_provider_from_config("providers.activityrefdata", entry))
|
|
for entry in config.get("callsign_data_providers", []):
|
|
self.callsign_data_providers.append(create_provider_from_config("providers.callsigndata", entry))
|
|
|
|
@staticmethod
|
|
def start_providers(providers, provider_type):
|
|
"""Helper method to activate enabled providers in the list."""
|
|
|
|
logger.info(f"Starting {provider_type} providers...")
|
|
for p in providers:
|
|
if p.enabled:
|
|
p.start()
|
|
|
|
def start(self):
|
|
# Start data providers before spot/alert providers so the lookup data is there already for incoming spots.
|
|
# Each category is fired off after a small delay to give the rest of Spothole chance to start up.
|
|
self._startup_timers = [
|
|
threading.Timer(5.0, lambda: self.start_providers(self.static_data_providers, "static data")),
|
|
threading.Timer(10.0, lambda: self.start_providers(self.callsign_data_providers, "callsign data")),
|
|
threading.Timer(15.0, lambda: self.start_providers(self.spot_providers, "spot")),
|
|
threading.Timer(20.0, lambda: self.start_providers(self.alert_providers, "alert")),
|
|
threading.Timer(
|
|
25.0,
|
|
lambda: self.start_providers(self.solar_condition_providers, "solar condition"),
|
|
),
|
|
threading.Timer(30.0, lambda: self.start_providers(self.sig_ref_data_providers, "activity ref data")),
|
|
]
|
|
for t in self._startup_timers:
|
|
t.daemon = True
|
|
t.start()
|
|
|
|
def stop(self):
|
|
# Cancel any startup timers that haven't fired yet
|
|
for t in self._startup_timers:
|
|
t.cancel()
|
|
|
|
# Stop all providers
|
|
all_providers = [
|
|
p
|
|
for p in (
|
|
self.spot_providers
|
|
+ self.alert_providers
|
|
+ self.solar_condition_providers
|
|
+ self.sig_ref_data_providers
|
|
+ self.static_data_providers
|
|
+ self.callsign_data_providers
|
|
)
|
|
if p.enabled
|
|
]
|
|
if not all_providers:
|
|
return
|
|
|
|
def stop_provider(p):
|
|
try:
|
|
p.stop()
|
|
except Exception:
|
|
logger.exception("Exception stopping provider")
|
|
|
|
threads = [threading.Thread(target=stop_provider, args=(p,), daemon=True) for p in all_providers]
|
|
for t in threads:
|
|
t.start()
|
|
|
|
deadline = time.monotonic() + 40
|
|
for t in threads:
|
|
t.join(timeout=max(0.0, deadline - time.monotonic()))
|
|
still_running = [t for t in threads if t.is_alive()]
|
|
if still_running:
|
|
logger.warning("Some threads did not stop in time!")
|
|
|
|
|
|
# Global object
|
|
DATA_PROVIDERS = DataProviders()
|