changeset 2096:0e7d8349087c

WIP port effectSequencer to asyncio
author drewp@bigasterisk.com
date Tue, 31 May 2022 00:13:20 -0700
parents ce8b66e68cd5
children ffd0a84d54f2
files light9/effect/sequencer/sequencer.py light9/effect/sequencer/service.py
diffstat 2 files changed, 61 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/light9/effect/sequencer/sequencer.py	Tue May 31 00:12:51 2022 -0700
+++ b/light9/effect/sequencer/sequencer.py	Tue May 31 00:13:20 2022 -0700
@@ -9,7 +9,6 @@
 from twisted.internet.defer import Deferred, inlineCallbacks
 from twisted.internet.inotify import INotify
 from twisted.python.filepath import FilePath
-import cyclone.sse
 import logging, bisect, time
 import traceback
 from decimal import Decimal
@@ -259,30 +258,3 @@
         # (sometimes it's None, not sure why, and neither is mypy)
         #if isinstance(sendSecs, float):
         #    metrics('update_s3_send_client').observe(sendSecs)
-
-
-class Updates(cyclone.sse.SSEHandler):
-
-    def __init__(self, application, request, **kwargs) -> None:
-        cyclone.sse.SSEHandler.__init__(self, application, request, **kwargs)
-        self.state: Dict = {}
-        dispatcher.connect(self.updateState, 'state')
-        self.numConnected = 0
-
-    def updateState(self, update: Dict):
-        self.state.update(update)
-
-    def bind(self) -> None:
-        self.numConnected += 1
-
-        if self.numConnected == 1:
-            self.loop()
-
-    def loop(self) -> None:
-        if self.numConnected == 0:
-            return
-        self.sendEvent(self.state)
-        reactor.callLater(.1, self.loop)
-
-    def unbind(self) -> None:
-        self.numConnected -= 1
--- a/light9/effect/sequencer/service.py	Tue May 31 00:12:51 2022 -0700
+++ b/light9/effect/sequencer/service.py	Tue May 31 00:13:20 2022 -0700
@@ -16,69 +16,69 @@
 
 from light9 import clientsession
 
-
-class App(object):
-
-    def __init__(self, show, session):
-        self.show = show
-        self.session = session
-
-        self.graph = SyncedGraph(networking.rdfdb.url, "effectSequencer")
-        self.graph.initiallySynced.addCallback(self.launch)
-
-    def launch(self, *args):
-        self.seq = Sequencer(
-            self.graph,
-            lambda settings: sendToCollector(
-                'effectSequencer',
-                self.session,
-                settings,
-                # This seems to be safe here (and lets us get from
-                # 20fpx to 40fpx), even though it leads to big stalls
-                # if I use it on KC.
-                useZmq=True))
-
-        self.cycloneApp = cyclone.web.Application(handlers=[
-            (r'/()', cyclone.web.StaticFileHandler, {
-                "path": "light9/effect/",
-                "default_filename": "sequencer.html"
-            }),
-            (r'/updates', Updates),
-            metricsRoute(),
-        ],
-                                                  debug=True,
-                                                  seq=self.seq,
-                                                  graph=self.graph,
-                                                #   stats=self.stats
-                                                  )
-        reactor.listenTCP(networking.effectSequencer.port, self.cycloneApp)
-        log.info("listening on %s" % networking.effectSequencer.port)
+from prometheus_client import Summary
+from rdfdb.syncedgraph.syncedgraph import SyncedGraph
+from starlette.applications import Starlette
+from starlette.endpoints import WebSocketEndpoint
+from starlette.responses import Response
+from starlette.routing import Route, WebSocketRoute
+from starlette.types import Receive, Scope, Send
+from starlette.websockets import WebSocket
+from starlette_exporter import PrometheusMiddleware, handle_metrics
 
 
-if __name__ == "__main__":
-    parser = optparse.OptionParser()
-    parser.add_option(
-        '--show',
-        help='show URI, like http://light9.bigasterisk.com/show/dance2008',
-        default=showconfig.showUri())
-    parser.add_option("-v",
-                      "--verbose",
-                      action="store_true",
-                      help="logging.DEBUG")
-    parser.add_option("--twistedlog",
-                      action="store_true",
-                      help="twisted logging")
-    clientsession.add_option(parser)
-    (options, args) = parser.parse_args()
-    log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
+# class Updates(cyclone.sse.SSEHandler):
+
+#     def __init__(self, application, request, **kwargs) -> None:
+#         cyclone.sse.SSEHandler.__init__(self, application, request, **kwargs)
+#         self.state: Dict = {}
+#         dispatcher.connect(self.updateState, 'state')
+#         self.numConnected = 0
+
+#     def updateState(self, update: Dict):
+#         self.state.update(update)
+
+#     def bind(self) -> None:
+#         self.numConnected += 1
+
+#         if self.numConnected == 1:
+#             self.loop()
+
+#     def loop(self) -> None:
+#         if self.numConnected == 0:
+#             return
+#         self.sendEvent(self.state)
+#         reactor.callLater(.1, self.loop)
+
+#     def unbind(self) -> None:
+#         self.numConnected -= 1
 
-    if not options.show:
-        raise ValueError("missing --show http://...")
+def main():
+    # session = clientsession.getUri('effectSequencer', options)
+    graph = SyncedGraph(networking.rdfdb.url, "effectSequencer")
 
-    session = clientsession.getUri('effectSequencer', options)
+    seq = Sequencer(
+        graph,
+        lambda settings: sendToCollector(
+            'effectSequencer',
+            '',#session,
+            settings,
+            # This seems to be safe here (and lets us get from
+            # 20fpx to 40fpx), even though it leads to big stalls
+            # if I use it on KC.
+            useZmq=True))
 
-    app = App(URIRef(options.show), session)
-    if options.twistedlog:
-        from twisted.python import log as twlog
-        twlog.startLogging(sys.stderr)
-    reactor.run()
+    app = Starlette(
+        debug=True,
+        routes=[
+            # WebSocketRoute('/updates', endpoint=functools.partial(Updates, listeners)),
+        ],
+    )
+
+    app.add_middleware(PrometheusMiddleware)
+    app.add_route("/metrics", handle_metrics)
+
+    return app
+
+
+app = main()