Skip to content

Commit

Permalink
Upgrade Tornado to v6, and fix servers accordingly. (#1181)
Browse files Browse the repository at this point in the history
Also updated the README for web_gui development
  • Loading branch information
glados-verma authored Oct 30, 2024
1 parent 945c089 commit 2064831
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 20 deletions.
2 changes: 2 additions & 0 deletions openhtf/output/servers/station_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
aggregate info from multiple station servers with a single frontend.
"""

import asyncio
import contextlib
import itertools
import json
Expand Down Expand Up @@ -166,6 +167,7 @@ def __init__(self, update_callback):

def run(self):
"""Call self._poll_for_update() in a loop and handle errors."""
asyncio.set_event_loop(asyncio.new_event_loop())
while True:
try:
self._poll_for_update()
Expand Down
51 changes: 35 additions & 16 deletions openhtf/output/servers/web_gui_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
# limitations under the License.
"""Extensible HTTP server serving the OpenHTF Angular frontend."""

import asyncio
import os
import threading
import time

import tornado.httpclient
import tornado.httpserver
Expand Down Expand Up @@ -112,6 +112,8 @@ class WebGuiServer(threading.Thread):

def __init__(self, additional_routes, port, sockets=None):
super(WebGuiServer, self).__init__(name=type(self).__name__)
self.ts_event = threading.Event()
self._running = asyncio.Event()

# Set up routes.
routes = [
Expand All @@ -121,24 +123,17 @@ def __init__(self, additional_routes, port, sockets=None):
}),
]
routes.extend(additional_routes)

if sockets is None:
sockets, self.port = bind_port(port)
else:
if not port:
raise ValueError('When sockets are passed to the server, port must be '
'specified and nonzero.')
self.port = port
self._sockets = sockets
self.port = port
self._loop = None

# Configure the Tornado application.
application = tornado.web.Application(
self.application = tornado.web.Application(
routes,
default_handler_class=DefaultHandler,
template_loader=TemplateLoader(STATIC_FILES_ROOT),
static_path=STATIC_FILES_ROOT,
)
self.server = tornado.httpserver.HTTPServer(application)
self.server.add_sockets(sockets)

def __enter__(self):
self.start()
Expand All @@ -147,14 +142,38 @@ def __enter__(self):
def __exit__(self, *unused_args):
self.stop()

async def run_app(self):
"""Runs the station server application."""
self.ts_watchdog_task = asyncio.create_task(self._stop_threadsafe())
if self._sockets is None:
self._sockets, self.port = bind_port(self.port)
else:
if not self.port:
raise ValueError(
'When sockets are passed to the server, port must be '
'specified and nonzero.'
)
self.server = tornado.httpserver.HTTPServer(self.application)
self.server.add_sockets(self._sockets)
await self._running.wait()
await self.ts_watchdog_task
await self.server.close_all_connections()

async def _stop_threadsafe(self):
"""Handles stopping the server in a threadsafe manner."""
while not self.ts_event.is_set():
await asyncio.sleep(0.1)
self._running.set()

def _get_config(self):
"""Override this to configure the Angular app."""
return {}

def run(self):
tornado.ioloop.IOLoop.instance().start() # Blocking IO loop.
"""Runs the station server."""
asyncio.run(self.run_app())

def stop(self):
self.server.stop()
ioloop = tornado.ioloop.IOLoop.instance()
ioloop.add_timeout(time.time() + _SERVER_SHUTDOWN_BUFFER_S, ioloop.stop)
"""Stops the station server. Method is threadsafe."""
self.ts_event.set()

15 changes: 13 additions & 2 deletions openhtf/output/web_gui/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# OpenHTF web GUI client

## Prerequisites

Follow the steps from [CONTRIBUTING.md](../../../CONTRIBUTING.md) to set up
the Python virtual environment. Make sure you have done an "editable" install.

## Development

First, start the dashboard server on the default port by running the following
Start the dashboard server on the default port by running the following
from the project root directory:

```
Expand All @@ -22,4 +27,10 @@ the dashboard server and should reload automatically when changes are made to
frontend files.

With the dashboard running, you can run OpenHTF tests separately, and they
should be picked up over multicast and appear on the dashboard.
should be picked up over multicast and appear on the dashboard. To test things
out, you can run the frontend example test:

```
python3 examples/frontend_example.py
```

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "openhtf"
version = "1.6.0"
version = "1.6.1"
authors = [
{ name="The OpenHTF Authors"},
]
Expand All @@ -23,7 +23,7 @@ dependencies = [
"pyOpenSSL>=17.1.0",
"requests>=2.27.1",
"sockjs_tornado>=1.0.7",
"tornado>=4.3,<5.0",
"tornado>=6,<6.3",
"typing_extensions>=4.12.2",
]
license = {file = "LICENSE"}
Expand Down

0 comments on commit 2064831

Please sign in to comment.