aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fg21sim/webui/app.py30
-rw-r--r--fg21sim/webui/handlers/websocket.py4
2 files changed, 24 insertions, 10 deletions
diff --git a/fg21sim/webui/app.py b/fg21sim/webui/app.py
index 9bc7029..e234263 100644
--- a/fg21sim/webui/app.py
+++ b/fg21sim/webui/app.py
@@ -2,19 +2,17 @@
# MIT license
"""
-Web user interface (UI) of "fg21sim" based upon Tornado_ web server and
-using the WebSocket_ protocol.
+Web user interface (UI) of "fg21sim" based upon Tornado_ web server.
.. _Tornado: http://www.tornadoweb.org/
-
-.. _WebSocket: https://en.wikipedia.org/wiki/WebSocket ,
- http://caniuse.com/#feat=websockets
"""
import os
+from concurrent.futures import ThreadPoolExecutor
import tornado.web
from tornado.web import url
+from tornado.options import define, options
from .handlers import (IndexHandler,
LoginHandler,
@@ -25,6 +23,11 @@ from .utils import gen_cookie_secret
from ..configs import ConfigManager
+# Each module defines its own options, which are added to the global namespace
+define("max_workers", default=1, type=int,
+ help="Maximum number of threads to execute the submitted tasks")
+
+
class Application(tornado.web.Application):
"""
Application of the "fg21sim" Web UI.
@@ -36,15 +39,26 @@ class Application(tornado.web.Application):
status. The configuration operations (e.g., "set", "get", "load")
are performed on this instance, which is also passed to the
foregrounds simulation programs.
- ws_clients : set
- Current connected clients through WebSocket.
+ websockets : set of `~tornado.websocket.WebSocketHandler`
+ Current active WebSockets opened by clients.
When a new WebSocket connection established, it is added to this
list, which is also removed from this list when the connection lost.
+ executor : `~concurrent.futures.ThreadPoolExecutor`
+ An executor that uses a pool of threads to execute the submitted
+ tasks asynchronously.
+ task_status : dict
+ Whether the task is running and/or finished?
+ 1. running=False, finished=False: not started
+ 2. running=False, finished=True: finished
+ 3. running=True, finished=False: running
+ 4. running=True, finished=True: ?? error ??
"""
def __init__(self, **kwargs):
self.configmanager = ConfigManager()
- self.ws_clients = set()
+ self.websockets = set()
+ self.executor = ThreadPoolExecutor(max_workers=options.max_workers)
+ self.task_status = {"running": False, "finished": False}
# URL handlers
handlers = [
url(r"/", IndexHandler, name="index"),
diff --git a/fg21sim/webui/handlers/websocket.py b/fg21sim/webui/handlers/websocket.py
index a772aa8..e84c20c 100644
--- a/fg21sim/webui/handlers/websocket.py
+++ b/fg21sim/webui/handlers/websocket.py
@@ -103,7 +103,7 @@ class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
"""Invoked when a new WebSocket is opened by the client."""
# Add to the set of current connected clients
- self.application.ws_clients.add(self)
+ self.application.websockets.add(self)
logger.info("Added new opened WebSocket client: {0}".format(self))
self.configs = self.application.configmanager
# Push current configurations to the client
@@ -112,7 +112,7 @@ class WSHandler(tornado.websocket.WebSocketHandler):
def on_close(self):
"""Invoked when a new WebSocket is closed by the client."""
# Remove from the set of current connected clients
- self.application.ws_clients.remove(self)
+ self.application.websockets.remove(self)
logger.warning("Removed closed WebSocket client: {0}".format(self))
def broadcast(self, message):