[core] Re-organize

This commit is contained in:
Derek 2023-08-14 10:53:30 -04:00
parent 272532b389
commit 36c2873532
3 changed files with 52 additions and 52 deletions
ovtk_audiencekit

View file

@ -22,8 +22,7 @@ from ovtk_audiencekit.core import WebsocketServerProcess
from ovtk_audiencekit.core.Config import kdl_parse_config, kdl_reserved
from ovtk_audiencekit.events import Event, Delete
from ovtk_audiencekit.chats.ChatProcess import ShutdownRequest
from ovtk_audiencekit.plugins import builtins
from ovtk_audiencekit.plugins.PluginBase import PluginError
from ovtk_audiencekit.plugins import builtins, PluginError
logger = logging.getLogger(__name__)
@ -118,6 +117,27 @@ class MainProcess:
event = pipe.recv()
self.event_queue.put_nowait(event)
def _setup_webserver(self):
self.webserver = Quart(__name__, static_folder=None, template_folder=None)
listen = ':'.join(self.web_conf)
self.webserver.config['SERVER_NAME'] = listen
async def serve_coro():
config = hypercorn.config.Config()
config.bind = listen
config.use_reloader = False
config.logger_class = HypercornLoggingShim
try:
await hypercorn.asyncio.serve(self.webserver, config, shutdown_trigger=self.shutdown_ev.wait)
except Exception as e:
logger.critical(f'Failure in web process - {e}')
logger.debug(''.join(format_exception(None, e, e.__traceback__)))
raise e
# MAGIC: As root tasks are supposed to be infinte loops, raise an exception if hypercorn shut down
raise asyncio.CancelledError()
return serve_coro()
async def handle_events(self):
while True:
event = await self.event_queue.get()
@ -152,7 +172,20 @@ class MainProcess:
else:
logger.error(f'Unknown data in event loop - {event}')
def user_setup(self):
async def tick_plugins(self):
while True:
await asyncio.sleep(0.5)
for plugin_name, plugin in list(self.plugins.items()):
try:
res = plugin.tick(0.5) # Not necesarily honest!
if asyncio.iscoroutinefunction(plugin.tick):
await res
except Exception as e:
logger.critical(f'Failure during background processing for {plugin_name} ({e}) - disabling...')
logger.debug(''.join(format_exception(None, e, e.__traceback__)))
self._unload_plugin(plugin_name)
async def user_setup(self):
config = kdl.Document(list(parse_kdl_deep(self.config_path)))
stdin_lock = Lock()
# Load secrets
@ -242,41 +275,6 @@ class MainProcess:
del self.plugins[plugin_name]
sys.path = self._initial_syspath
async def tick_plugins(self):
while True:
await asyncio.sleep(0.5)
for plugin_name, plugin in list(self.plugins.items()):
try:
res = plugin.tick(0.5) # Not necesarily honest!
if asyncio.iscoroutinefunction(plugin.tick):
await res
except Exception as e:
logger.critical(f'Failure during background processing for {plugin_name} ({e}) - disabling...')
logger.debug(''.join(format_exception(None, e, e.__traceback__)))
self._unload_plugin(plugin_name)
def _setup_webserver(self):
self.webserver = Quart(__name__, static_folder=None, template_folder=None)
listen = ':'.join(self.web_conf)
self.webserver.config['SERVER_NAME'] = listen
async def serve_coro():
config = hypercorn.config.Config()
config.bind = listen
config.use_reloader = False
config.logger_class = HypercornLoggingShim
try:
await hypercorn.asyncio.serve(self.webserver, config, shutdown_trigger=self.shutdown_ev.wait)
except Exception as e:
logger.critical(f'Failure in web process - {e}')
logger.debug(''.join(format_exception(None, e, e.__traceback__)))
raise e
# MAGIC: As root tasks are supposed to be infinte loops, raise an exception if hypercorn shut down
raise asyncio.CancelledError()
return serve_coro()
async def run(self):
self.shutdown_ev = asyncio.Event()
self.reload_ev = asyncio.Event()
@ -314,7 +312,7 @@ class MainProcess:
# User (plugin / chat) mode (reloading allowed)
while True:
async with self.webserver.app_context():
self.user_setup()
await self.user_setup()
# Start plumbing tasks
user_tasks.add(loop.create_task(self.tick_plugins()))
user_tasks.add(loop.create_task(self.handle_events()))
@ -341,7 +339,7 @@ class MainProcess:
except KeyboardInterrupt:
pass
except kdl.errors.ParseError as e:
if (e.file):
if e.file:
logger.critical(f'Invalid configuration in {e.file} at {e.line}:{e.col} - {e.msg}')
else:
logger.critical(f'Invalid configuration - {e.msg}')

View file

@ -31,6 +31,14 @@ class GetitemFormatter(Formatter):
return (field, keys[0])
class OvtkBlueprint(quart.Blueprint):
def url_for(self, endpoint, *args, **kwargs):
"""url_for method that understands blueprint-relative names under non-request contexts"""
if endpoint.startswith('.'):
endpoint = self.name + endpoint
return quart.url_for(endpoint, *args, **kwargs)
class PluginBase(ABC):
plugins = {}
@ -46,17 +54,11 @@ class PluginBase(ABC):
# HACK: This is kinda gross, and probably wont be true for frozen modules
plugin_dir = os.path.dirname(sys.modules[self.__class__.__module__].__file__)
self.blueprint = quart.Blueprint(self._name, __name__,
url_prefix=f'/{self._name}',
static_url_path='static',
static_folder=os.path.join(plugin_dir, 'static'),
template_folder=os.path.join(plugin_dir, 'templates'))
def url_for(endpoint, *args, **kwargs):
"""Monkey-patched url_for method that understands blueprint-relative names, even under non-request contexts"""
if endpoint.startswith('.'):
endpoint = self._name + endpoint
return quart.url_for(endpoint, *args, **kwargs)
self.blueprint.url_for = url_for
self.blueprint = OvtkBlueprint(self._name, __name__,
url_prefix=f'/{self._name}',
static_url_path='static',
static_folder=os.path.join(plugin_dir, 'static'),
template_folder=os.path.join(plugin_dir, 'templates'))
if _children:
raise ValueError('Module does not accept children')

View file

@ -1,3 +1,3 @@
from .PluginBase import PluginBase, PluginError
from ovtk_audiencekit.core.PluginBase import PluginBase, PluginError
__all__ = ['PluginBase', 'PluginError']