Add run_in_main_thread as helper for those wanting to run server code from web view. Resolve #2457

This commit is contained in:
Griatch 2022-02-12 18:44:38 +01:00
parent 9ee97d9b6c
commit a17fa2a454
3 changed files with 23 additions and 1 deletions

View file

@ -151,6 +151,8 @@ Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10
`LUNR_STOP_WORD_FILTER_EXCEPTIONS` can be extended to make sure common names are included.
- Add `.deserialize()` method to `_Saver*` structures to help completely
decouple structures from database without needing separate import.
- Add `run_in_main_thread` as a helper for those wanting to code server code
from a web view.
## Evennia 0.9.5

View file

@ -41,7 +41,7 @@ PROC_MODIFIED_OBJS = WeakValueDictionary()
_SELF_PID = os.getpid()
_SERVER_PID, _PORTAL_PID = get_evennia_pids()
_IS_SUBPROCESS = (_SERVER_PID and _PORTAL_PID) and _SELF_PID not in (_SERVER_PID, _PORTAL_PID)
_IS_MAIN_THREAD = threading.currentThread().getName() == "MainThread"
_IS_MAIN_THREAD = threading.current_thread().name == "MainThread"
class SharedMemoryModelBase(ModelBase):

View file

@ -11,6 +11,7 @@ import gc
import sys
import types
import math
import threading
import re
import textwrap
import random
@ -41,6 +42,8 @@ from evennia.utils import logger
_MULTIMATCH_TEMPLATE = settings.SEARCH_MULTIMATCH_TEMPLATE
_EVENNIA_DIR = settings.EVENNIA_DIR
_GAME_DIR = settings.GAME_DIR
_IS_MAIN_THREAD = threading.current_thread().name == "MainThread"
ENCODINGS = settings.ENCODINGS
_TASK_HANDLER = None
@ -2691,3 +2694,20 @@ def copy_word_case(base_word, new_word):
)
+ excess
)
def run_in_main_thread(function_or_method, *args, **kwargs):
"""
Force a callable to execute in the main Evennia thread. This is only relevant when
calling code from e.g. web views, which run in a separate threadpool. Use this
to avoid race conditions.
Args:
function_or_method (callable): A function or method to fire.
*args: Will be passed into the callable.
**kwargs: Will be passed into the callable.
"""
if _IS_MAIN_THREAD:
return function_or_method(*args, **kwargs)
else:
return threads.blockingCallFromThread(reactor, function_or_method, *args, **kwargs)