mirror of
https://github.com/liamcottle/reticulum-meshchat.git
synced 2026-04-27 16:10:32 +00:00
rework async utils to always use main event loop in threadsafe manner
This commit is contained in:
parent
747236ae8b
commit
65df111b87
2 changed files with 18 additions and 15 deletions
|
|
@ -2038,6 +2038,9 @@ class ReticulumMeshChat:
|
|||
# called when web app has started
|
||||
async def on_startup(app):
|
||||
|
||||
# remember main event loop
|
||||
AsyncUtils.set_main_loop(asyncio.get_event_loop())
|
||||
|
||||
# auto launch web browser
|
||||
if launch_browser:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
import asyncio
|
||||
from typing import Coroutine
|
||||
|
||||
|
||||
class AsyncUtils:
|
||||
|
||||
# this method allows running the provided async coroutine from within a sync function
|
||||
# it will run the async function on the existing event loop if available, otherwise it will start a new event loop
|
||||
# remember main loop
|
||||
main_loop: asyncio.AbstractEventLoop | None = None
|
||||
|
||||
@staticmethod
|
||||
def run_async(coroutine):
|
||||
def set_main_loop(loop: asyncio.AbstractEventLoop):
|
||||
AsyncUtils.main_loop = loop
|
||||
|
||||
# attempt to get existing event loop
|
||||
existing_event_loop = None
|
||||
try:
|
||||
existing_event_loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
# 'RuntimeError: no running event loop'
|
||||
pass
|
||||
# this method allows running the provided async coroutine from within a sync function
|
||||
# it will run the async function on the main event loop if possible, otherwise it logs a warning
|
||||
@staticmethod
|
||||
def run_async(coroutine: Coroutine):
|
||||
|
||||
# if there is an existing event loop running, submit the coroutine to that loop
|
||||
if existing_event_loop and existing_event_loop.is_running():
|
||||
existing_event_loop.create_task(coroutine)
|
||||
# run provided coroutine on main event loop, ensuring thread safety
|
||||
if AsyncUtils.main_loop and AsyncUtils.main_loop.is_running():
|
||||
asyncio.run_coroutine_threadsafe(coroutine, AsyncUtils.main_loop)
|
||||
return
|
||||
|
||||
# otherwise start a new event loop to run the coroutine
|
||||
asyncio.run(coroutine)
|
||||
# main event loop not running...
|
||||
print("WARNING: Main event loop not available. Could not schedule task.")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue