add source "busy state" to improve background scheduling
This commit is contained in:
parent
097f8a2b82
commit
a36f106c72
@ -110,7 +110,6 @@ class ServiceScheduler(object):
|
|||||||
def __init__(self, source, schedule):
|
def __init__(self, source, schedule):
|
||||||
self.source = source
|
self.source = source
|
||||||
self.schedule = Schedule.parse(schedule)
|
self.schedule = Schedule.parse(schedule)
|
||||||
self.active = False
|
|
||||||
self.source.addClient(self)
|
self.source.addClient(self)
|
||||||
self.selectionTimer = None
|
self.selectionTimer = None
|
||||||
self.source.getProps().collect("center_freq", "samp_rate").wire(self.onFrequencyChange)
|
self.source.getProps().collect("center_freq", "samp_rate").wire(self.onFrequencyChange)
|
||||||
@ -133,8 +132,8 @@ class ServiceScheduler(object):
|
|||||||
if self.selectionTimer:
|
if self.selectionTimer:
|
||||||
self.selectionTimer.cancel()
|
self.selectionTimer.cancel()
|
||||||
|
|
||||||
def isActive(self):
|
def getClientClass(self):
|
||||||
return self.active
|
return SdrSource.CLIENT_BACKGROUND
|
||||||
|
|
||||||
def onStateChange(self, state):
|
def onStateChange(self, state):
|
||||||
if state == SdrSource.STATE_STOPPING:
|
if state == SdrSource.STATE_STOPPING:
|
||||||
@ -142,13 +141,16 @@ class ServiceScheduler(object):
|
|||||||
elif state == SdrSource.STATE_FAILED:
|
elif state == SdrSource.STATE_FAILED:
|
||||||
self.cancelTimer()
|
self.cancelTimer()
|
||||||
|
|
||||||
|
def onBusyStateChange(self, state):
|
||||||
|
if state == SdrSource.BUSYSTATE_IDLE:
|
||||||
|
self.scheduleSelection()
|
||||||
|
|
||||||
def onFrequencyChange(self, name, value):
|
def onFrequencyChange(self, name, value):
|
||||||
self.scheduleSelection()
|
self.scheduleSelection()
|
||||||
|
|
||||||
def selectProfile(self):
|
def selectProfile(self):
|
||||||
self.active = False
|
if self.source.hasClients(SdrSource.CLIENT_USER):
|
||||||
if self.source.hasActiveClients():
|
logger.debug("source has active users; not touching")
|
||||||
logger.debug("source has active clients; not touching")
|
|
||||||
return
|
return
|
||||||
logger.debug("source seems to be idle, selecting profile for background services")
|
logger.debug("source seems to be idle, selecting profile for background services")
|
||||||
entry = self.schedule.getCurrentEntry()
|
entry = self.schedule.getCurrentEntry()
|
||||||
@ -164,7 +166,6 @@ class ServiceScheduler(object):
|
|||||||
self.scheduleSelection(entry.getScheduledEnd())
|
self.scheduleSelection(entry.getScheduledEnd())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.active = True
|
|
||||||
self.source.activateProfile(entry.getProfile())
|
self.source.activateProfile(entry.getProfile())
|
||||||
self.source.start()
|
self.source.start()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -186,8 +187,8 @@ class ServiceHandler(object):
|
|||||||
if "schedule" in props:
|
if "schedule" in props:
|
||||||
self.scheduler = ServiceScheduler(self.source, props["schedule"])
|
self.scheduler = ServiceScheduler(self.source, props["schedule"])
|
||||||
|
|
||||||
def isActive(self):
|
def getClientClass(self):
|
||||||
return False
|
return SdrSource.CLIENT_BACKGROUND
|
||||||
|
|
||||||
def onStateChange(self, state):
|
def onStateChange(self, state):
|
||||||
if state == SdrSource.STATE_RUNNING:
|
if state == SdrSource.STATE_RUNNING:
|
||||||
@ -199,6 +200,9 @@ class ServiceHandler(object):
|
|||||||
logger.debug("sdr source failed; stopping services.")
|
logger.debug("sdr source failed; stopping services.")
|
||||||
self.stopServices()
|
self.stopServices()
|
||||||
|
|
||||||
|
def onBusyStateChange(self, state):
|
||||||
|
pass
|
||||||
|
|
||||||
def isSupported(self, mode):
|
def isSupported(self, mode):
|
||||||
# TODO this should be in a more central place (the frontend also needs this)
|
# TODO this should be in a more central place (the frontend also needs this)
|
||||||
requirements = {
|
requirements = {
|
||||||
|
@ -107,6 +107,13 @@ class SdrSource(object):
|
|||||||
STATE_TUNING = 4
|
STATE_TUNING = 4
|
||||||
STATE_FAILED = 5
|
STATE_FAILED = 5
|
||||||
|
|
||||||
|
BUSYSTATE_IDLE = 0
|
||||||
|
BUSYSTATE_BUSY = 1
|
||||||
|
|
||||||
|
CLIENT_INACTIVE = 0
|
||||||
|
CLIENT_BACKGROUND = 1
|
||||||
|
CLIENT_USER = 2
|
||||||
|
|
||||||
def __init__(self, id, props, port):
|
def __init__(self, id, props, port):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.props = props
|
self.props = props
|
||||||
@ -126,6 +133,7 @@ class SdrSource(object):
|
|||||||
self.modificationLock = threading.Lock()
|
self.modificationLock = threading.Lock()
|
||||||
self.failed = False
|
self.failed = False
|
||||||
self.state = SdrSource.STATE_STOPPED
|
self.state = SdrSource.STATE_STOPPED
|
||||||
|
self.busyState = SdrSource.BUSYSTATE_IDLE
|
||||||
|
|
||||||
def getEventNames(self):
|
def getEventNames(self):
|
||||||
return ["samp_rate", "nmux_memory", "center_freq", "ppm", "rf_gain", "lna_gain", "rf_amp", "antenna", "if_gain"]
|
return ["samp_rate", "nmux_memory", "center_freq", "ppm", "rf_gain", "lna_gain", "rf_amp", "antenna", "if_gain"]
|
||||||
@ -285,21 +293,28 @@ class SdrSource(object):
|
|||||||
def sleepOnRestart(self):
|
def sleepOnRestart(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def hasActiveClients(self):
|
def hasClients(self, *args):
|
||||||
activeClients = [c for c in self.clients if c.isActive()]
|
clients = [c for c in self.clients if c.getClientClass() in args]
|
||||||
return len(activeClients) > 0
|
return len(clients) > 0
|
||||||
|
|
||||||
def addClient(self, c):
|
def addClient(self, c):
|
||||||
self.clients.append(c)
|
self.clients.append(c)
|
||||||
if self.hasActiveClients():
|
hasUsers = self.hasClients(SdrSource.CLIENT_USER)
|
||||||
|
hasBackgroundTasks = self.hasClients(SdrSource.CLIENT_BACKGROUND)
|
||||||
|
if hasUsers or hasBackgroundTasks:
|
||||||
self.start()
|
self.start()
|
||||||
|
self.setBusyState(SdrSource.BUSYSTATE_BUSY if hasUsers else SdrSource.BUSYSTATE_IDLE)
|
||||||
|
|
||||||
def removeClient(self, c):
|
def removeClient(self, c):
|
||||||
try:
|
try:
|
||||||
self.clients.remove(c)
|
self.clients.remove(c)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
if not self.hasActiveClients():
|
|
||||||
|
hasUsers = self.hasClients(SdrSource.CLIENT_USER)
|
||||||
|
hasBackgroundTasks = self.hasClients(SdrSource.CLIENT_BACKGROUND)
|
||||||
|
self.setBusyState(SdrSource.BUSYSTATE_BUSY if hasUsers else SdrSource.BUSYSTATE_IDLE)
|
||||||
|
if not hasUsers and not hasBackgroundTasks:
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
def addSpectrumClient(self, c):
|
def addSpectrumClient(self, c):
|
||||||
@ -328,6 +343,13 @@ class SdrSource(object):
|
|||||||
for c in self.clients:
|
for c in self.clients:
|
||||||
c.onStateChange(state)
|
c.onStateChange(state)
|
||||||
|
|
||||||
|
def setBusyState(self, state):
|
||||||
|
if state == self.busyState:
|
||||||
|
return
|
||||||
|
self.busyState = state
|
||||||
|
for c in self.clients:
|
||||||
|
c.onBusyStateChange(state)
|
||||||
|
|
||||||
|
|
||||||
class Resampler(SdrSource):
|
class Resampler(SdrSource):
|
||||||
def __init__(self, props, port, sdr):
|
def __init__(self, props, port, sdr):
|
||||||
@ -575,8 +597,8 @@ class SpectrumThread(csdr.output):
|
|||||||
c.cancel()
|
c.cancel()
|
||||||
self.subscriptions = []
|
self.subscriptions = []
|
||||||
|
|
||||||
def isActive(self):
|
def getClientClass(self):
|
||||||
return True
|
return SdrSource.CLIENT_USER
|
||||||
|
|
||||||
def onStateChange(self, state):
|
def onStateChange(self, state):
|
||||||
if state in [SdrSource.STATE_STOPPING, SdrSource.STATE_FAILED]:
|
if state in [SdrSource.STATE_STOPPING, SdrSource.STATE_FAILED]:
|
||||||
@ -584,6 +606,9 @@ class SpectrumThread(csdr.output):
|
|||||||
elif state == SdrSource.STATE_RUNNING:
|
elif state == SdrSource.STATE_RUNNING:
|
||||||
self.dsp.start()
|
self.dsp.start()
|
||||||
|
|
||||||
|
def onBusyStateChange(self, state):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DspManager(csdr.output):
|
class DspManager(csdr.output):
|
||||||
def __init__(self, handler, sdrSource):
|
def __init__(self, handler, sdrSource):
|
||||||
@ -707,8 +732,8 @@ class DspManager(csdr.output):
|
|||||||
def setProperty(self, prop, value):
|
def setProperty(self, prop, value):
|
||||||
self.localProps.getProperty(prop).setValue(value)
|
self.localProps.getProperty(prop).setValue(value)
|
||||||
|
|
||||||
def isActive(self):
|
def getClientClass(self):
|
||||||
return True
|
return SdrSource.CLIENT_USER
|
||||||
|
|
||||||
def onStateChange(self, state):
|
def onStateChange(self, state):
|
||||||
if state == SdrSource.STATE_RUNNING:
|
if state == SdrSource.STATE_RUNNING:
|
||||||
@ -722,6 +747,9 @@ class DspManager(csdr.output):
|
|||||||
self.dsp.stop()
|
self.dsp.stop()
|
||||||
self.handler.handleSdrFailure("sdr device failed")
|
self.handler.handleSdrFailure("sdr device failed")
|
||||||
|
|
||||||
|
def onBusyStateChange(self, state):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CpuUsageThread(threading.Thread):
|
class CpuUsageThread(threading.Thread):
|
||||||
sharedInstance = None
|
sharedInstance = None
|
||||||
|
Loading…
Reference in New Issue
Block a user