changeset 2204:3db40ecf9e61

refactor setAttrs
author drewp@bigasterisk.com
date Mon, 22 May 2023 01:04:46 -0700
parents 615046dfe45f
children 71fa794c160c
files light9/collector/collector.py
diffstat 1 files changed, 47 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/light9/collector/collector.py	Mon May 22 01:03:18 2023 -0700
+++ b/light9/collector/collector.py	Mon May 22 01:04:46 2023 -0700
@@ -105,6 +105,48 @@
             end = typedValue(float, self.graph, remap, L9['end'])
             self.remapOut[(dev, attr)] = OutputRange((start, end))
 
+    def setAttrs(self, client: ClientType, clientSession: ClientSessionType, settings: DeviceSettings, sendTime: UnixTime):
+        """
+        Given DeviceSettings, we resolve conflicting values,
+        process them into output attrs, and call Output.update
+        to send the new outputs.
+
+        client is a string naming the type of client.
+        (client, clientSession) is a unique client instance.
+        clientSession is deprecated.
+
+        Each client session's last settings will be forgotten
+        after clientTimeoutSec.
+        """
+        # todo: cleanup session code if we really don't want to be able to run multiple sessions of one client
+        clientSession = ClientSessionType("no_longer_used")
+
+        now = UnixTime(time.time())
+        self._warnOnLateRequests(client, now, sendTime)
+
+        self._forgetStaleClients(now)
+
+        self.lastRequest[(client, clientSession)] = (now, self._resolvedSettingsDict(settings))
+
+        deviceAttrs = self._merge(iter(self.lastRequest.values()))
+
+        outputAttrsByDevice = self._convertToOutputAttrsPerDevice(deviceAttrs)
+        pendingOut = self._flattenDmxOutput(outputAttrsByDevice)
+
+        dt1 = time.time() - now
+
+        self._updateOutputs(pendingOut)
+
+        dt2 = time.time() - dt1
+        if dt1 > .030 or dt2 > .030:
+            log.warning("slow setAttrs: prepare %.1fms -> updateOutputs %.1fms" % (dt1 * 1000, dt2 * 1000))
+
+    def _warnOnLateRequests(self, client, now, sendTime):
+        requestLag = now - sendTime
+        if requestLag > .1 and now > self._initTime + 10 and getattr(self, '_lastWarnTime', 0) < now - 3:
+            self._lastWarnTime = now
+            log.warning('collector.setAttrs from %s is running %.1fms after the request was made', client, requestLag * 1000)
+
     def _forgetStaleClients(self, now):
         staleClientSessions = []
         for clientSession, (reqTime, _) in self.lastRequest.items():
@@ -125,12 +167,6 @@
                 out[(devUri, devAttr)] = val
         return out
 
-    def _warnOnLateRequests(self, client, now, sendTime):
-        requestLag = now - sendTime
-        if requestLag > .1 and now > self._initTime + 10 and getattr(self, '_lastWarnTime', 0) < now - 3:
-            self._lastWarnTime = now
-            log.warn('collector.setAttrs from %s is running %.1fms after the request was made', client, requestLag * 1000)
-
     def _merge(self, lastRequests):
         deviceAttrs: Dict[DeviceUri, Dict[DeviceAttr, VTUnion]] = {}  # device: {deviceAttr: value}
         for _, lastSettings in lastRequests:
@@ -157,51 +193,15 @@
 
         return deviceAttrs
 
-    def setAttrs(self, client: ClientType, clientSession: ClientSessionType, settings: DeviceSettings, sendTime: UnixTime):
-        """
-        settings is a list of (device, attr, value). These attrs are
-        device attrs. We resolve conflicting values, process them into
-        output attrs, and call Output.update to send the new outputs.
-
-        client is a string naming the type of client. (client,
-        clientSession) is a unique client instance.
-
-        Each client session's last settings will be forgotten after
-        clientTimeoutSec.
-        """
-        # todo: cleanup session code if we really don't want to be able to run multiple sessions of one client
-        clientSession = ClientSessionType("no_longer_used")
-
-        now = UnixTime(time.time())
-        self._warnOnLateRequests(client, now, sendTime)
-
-        self._forgetStaleClients(now)
-
-        self._acceptNewClientSessionSettings(client, clientSession, settings, now)
-
-        deviceAttrs = self._merge(iter(self.lastRequest.values()))
-
-        outputAttrs = cast(Dict[DeviceUri, Dict[OutputAttr, OutputValue]], {})
+    def _convertToOutputAttrsPerDevice(self, deviceAttrs):
+        ret: Dict[DeviceUri, Dict[OutputAttr, OutputValue]] = {}
         for d, devType in self._deviceType.items():
             try:
-                outputAttrs[d] = toOutputAttrs(devType, deviceAttrs.get(d, {}))
-                self.listeners.outputAttrsSet(d, outputAttrs[d], self._outputMap)
+                ret[d] = toOutputAttrs(devType, deviceAttrs.get(d, {}))
+                self.listeners.outputAttrsSet(d, ret[d], self._outputMap)
             except Exception as e:
                 log.error('failing toOutputAttrs on %s: %r', d, e)
-
-        pendingOut = self._flattenDmxOutput(outputAttrs)
-
-        dt1 = 1000 * (time.time() - now)
-
-        self._updateOutputs(pendingOut)
-
-        dt2 = 1000 * (time.time() - now) - dt1
-        if dt1 > 30 or dt2 > 30:
-            log.warn("slow setAttrs: prepare %.1fms -> updateOutputs %.1fms" % (dt1, dt2 - dt1))
-
-    def _acceptNewClientSessionSettings(self, client, clientSession, settings, now):
-        uniqueSettings = self.resolvedSettingsDict(settings)
-        self.lastRequest[(client, clientSession)] = (now, uniqueSettings)
+        return ret
 
     def _flattenDmxOutput(self, outputAttrs: Dict[DeviceUri, Dict[OutputAttr, OutputValue]]) -> Dict[OutputUri, bytearray]:
         pendingOut = cast(Dict[OutputUri, bytearray], {})