Move output_lock/output_buffer out of main

This commit is contained in:
Fierelier 2023-05-02 16:30:37 +02:00
parent a6b4e38cb6
commit 922a7791f3
2 changed files with 15 additions and 14 deletions

View File

@ -6,6 +6,7 @@ import readchar
import getpass import getpass
import textwrap import textwrap
import threading import threading
import queue
import platform import platform
if platform.system().startswith("Windows"): if platform.system().startswith("Windows"):
import win_unicode_console import win_unicode_console
@ -17,6 +18,16 @@ import app
contentapi = app.loadmod("contentapi") contentapi = app.loadmod("contentapi")
config = app.mod["main"].config config = app.mod["main"].config
# Output from the websocket can only get truly printed to the screen when this lock is released.
# We grab the lock when the user is in some kind of "input" mode, which blocks the websocket printing
# thread from processing the queue (if it has anything anyway)
output_lock = threading.Lock()
# Output from the websocket is ALWAYS buffered, and we use a thread-safe queue to add and remove
# output safely. We buffer all messages to ensure the order is preserved; if we SOMETIMES queued and
# SOMETIMES did not, we would need to be very careful about whether the queue was empty, which requires
# additional locking and etc.
output_buffer = queue.Queue()
MAXTITLE=25 MAXTITLE=25
MSGPREFIX=Back.GREEN + " " + Back.RESET + " " MSGPREFIX=Back.GREEN + " " + Back.RESET + " "
@ -70,7 +81,7 @@ def ws_onopen(ws):
# We get exclusive access to output while we're handling user input. This allows us to "pause" any output # We get exclusive access to output while we're handling user input. This allows us to "pause" any output
# the threaded output queue might want to do (we're more important) # the threaded output queue might want to do (we're more important)
with ws.output_lock: with output_lock:
if key == "h": if key == "h":
print(" -- Help menu / Controls --") print(" -- Help menu / Controls --")
for key, value in commands.items(): for key, value in commands.items():
@ -117,8 +128,8 @@ def ws_onopen(ws):
# Just a simple infinite loop which blocks on the queue until something is available # Just a simple infinite loop which blocks on the queue until something is available
def ws_print_loop(): def ws_print_loop():
while True: while True:
next_output = ws.output_buffer.get() next_output = output_buffer.get()
with ws.output_lock: with output_lock:
printr(next_output) printr(next_output)
# Set the main room; we want to wait until the websocket is open because this also sets your # Set the main room; we want to wait until the websocket is open because this also sets your
@ -203,7 +214,7 @@ def get_message_history_string(ws):
def ws_print(ws, output): def ws_print(ws, output):
# Queueing is supposed to be threadsafe, so just slap a new one in there. This will wake up # Queueing is supposed to be threadsafe, so just slap a new one in there. This will wake up
# the printing thread automatically # the printing thread automatically
ws.output_buffer.put(output) output_buffer.put(output)
# Set the room to listen to on the websocket. Will also update the userlist, if # Set the room to listen to on the websocket. Will also update the userlist, if
# it's appropriate to do so # it's appropriate to do so

View File

@ -4,7 +4,6 @@ import logging
import threading import threading
import toml import toml
import websocket import websocket
import queue
from colorama import Fore, Back, Style, init as colorama_init, ansi as colorama_ansi from colorama import Fore, Back, Style, init as colorama_init, ansi as colorama_ansi
import app import app
@ -74,15 +73,6 @@ def main():
ws.user_info = context.user_me() ws.user_info = context.user_me()
ws.main_config = config ws.main_config = config
ws.ignored = {} # Just a tracking list for fun stats ws.ignored = {} # Just a tracking list for fun stats
# Output from the websocket can only get truly printed to the screen when this lock is released.
# We grab the lock when the user is in some kind of "input" mode, which blocks the websocket printing
# thread from processing the queue (if it has anything anyway)
ws.output_lock = threading.Lock()
# Output from the websocket is ALWAYS buffered, and we use a thread-safe queue to add and remove
# output safely. We buffer all messages to ensure the order is preserved; if we SOMETIMES queued and
# SOMETIMES did not, we would need to be very careful about whether the queue was empty, which requires
# additional locking and etc.
ws.output_buffer = queue.Queue()
# Note that the current_room stuff is set on open if you've supplied a default room in config # Note that the current_room stuff is set on open if you've supplied a default room in config
ws.current_room = 0 ws.current_room = 0