improve shutdown handling

This commit is contained in:
Jakob Ketterl
2019-05-12 18:10:24 +02:00
parent 17a362fe7a
commit a85a6c694c
6 changed files with 58 additions and 31 deletions

View File

@ -1,5 +1,5 @@
from owrx.config import PropertyManager
from owrx.source import DspManager, CpuUsageThread, SdrService, ClientReporterThread
from owrx.source import DspManager, CpuUsageThread, SdrService, ClientRegistry
import json
import logging
@ -14,7 +14,7 @@ class OpenWebRxClient(object):
def __init__(self, conn):
self.conn = conn
ClientReporterThread.getSharedInstance().addClient(self)
ClientRegistry.getSharedInstance().addClient(self)
self.dsp = None
self.sdr = None
@ -68,10 +68,8 @@ class OpenWebRxClient(object):
def close(self):
self.stopDsp()
CpuUsageThread.getSharedInstance().remove_client(self)
try:
ClientReporterThread.getSharedInstance().removeClient(self)
except ValueError:
pass
ClientRegistry.getSharedInstance().removeClient(self)
self.conn.close()
logger.debug("connection closed")
def stopDsp(self):

View File

@ -3,7 +3,7 @@ import mimetypes
from datetime import datetime
from owrx.websocket import WebSocketConnection
from owrx.config import PropertyManager
from owrx.source import ClientReporterThread
from owrx.source import ClientRegistry
from owrx.connection import WebSocketMessageHandler
from owrx.version import openwebrx_version
@ -41,7 +41,7 @@ class StatusController(Controller):
"status": "active",
"name": pm["receiver_name"],
"op_email": pm["receiver_admin"],
"users": ClientReporterThread.getSharedInstance().clientCount(),
"users": ClientRegistry.getSharedInstance().clientCount(),
"users_max": pm["max_clients"],
"gps": pm["receiver_gps"],
"asl": pm["receiver_asl"],

View File

@ -10,7 +10,7 @@ logger = logging.getLogger(__name__)
class SdrHuUpdater(threading.Thread):
def __init__(self):
self.doRun = True
super().__init__()
super().__init__(daemon = True)
def update(self):
pm = PropertyManager.getSharedInstance()

View File

@ -467,6 +467,8 @@ class CpuUsageThread(threading.Thread):
c.write_cpu_usage(cpu_usage)
time.sleep(3)
logger.debug("cpu usage thread shut down")
if CpuUsageThread.sharedInstance == self:
CpuUsageThread.sharedInstance = None
def get_cpu_usage(self):
try:
@ -499,42 +501,49 @@ class CpuUsageThread(threading.Thread):
self.shutdown()
def shutdown(self):
if self.doRun:
if CpuUsageThread.sharedInstance == self:
CpuUsageThread.sharedInstance = None
self.doRun = False
self.doRun = False
class ClientReportingThread(threading.Thread):
def __init__(self, registry):
self.doRun = True
self.registry = registry
super().__init__()
def run(self):
while self.doRun:
self.registry.broadcast()
time.sleep(3)
def stop(self):
self.doRun = False
class TooManyClientsException(Exception):
pass
class ClientReporterThread(threading.Thread):
class ClientRegistry(object):
sharedInstance = None
@staticmethod
def getSharedInstance():
if ClientReporterThread.sharedInstance is None:
ClientReporterThread.sharedInstance = ClientReporterThread()
ClientReporterThread.sharedInstance.start()
ClientReporterThread.sharedInstance.doRun = True
return ClientReporterThread.sharedInstance
if ClientRegistry.sharedInstance is None:
ClientRegistry.sharedInstance = ClientRegistry()
return ClientRegistry.sharedInstance
def __init__(self):
self.doRun = True
self.clients = []
self.reporter = None
super().__init__()
def run(self):
while (self.doRun):
n = self.clientCount()
for c in self.clients:
c.write_clients(n)
time.sleep(3)
ClientReporterThread.sharedInstance = None
def broadcast(self):
n = self.clientCount()
for c in self.clients:
c.write_clients(n)
def addClient(self, client):
pm = PropertyManager.getSharedInstance()
if len(self.clients) >= pm["max_clients"]:
raise TooManyClientsException()
self.clients.append(client)
if self.reporter is None:
self.reporter = ClientReportingThread(self)
self.reporter.start()
def clientCount(self):
return len(self.clients)
@ -544,5 +553,6 @@ class ClientReporterThread(threading.Thread):
self.clients.remove(client)
except ValueError:
pass
if not self.clients:
self.doRun = False
if not self.clients and self.reporter is not None:
self.reporter.stop()
self.reporter = None

View File

@ -72,5 +72,20 @@ class WebSocketConnection(object):
else:
logger.warning("unsupported opcode: {0}".format(opcode))
def close(self):
try:
header = self.get_header(0, 8)
self.handler.wfile.write(header)
self.handler.wfile.flush()
except ValueError:
logger.exception("while writing close frame:")
try:
self.handler.finish()
self.handler.connection.close()
except Exception:
logger.exception("while closing connection:")
class WebSocketException(Exception):
pass