__init__.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import threading
  2. from .asyncbased import AsyncBasedSession
  3. from .base import AbstractSession
  4. from .threadbased import ThreadBasedWebIOSession
  5. from functools import wraps
  6. _session_type = AsyncBasedSession
  7. __all__ = ['set_session_implement', 'run_async', 'asyncio_coroutine', 'register_thread']
  8. def set_session_implement(session_type):
  9. global _session_type
  10. assert session_type in [ThreadBasedWebIOSession, AsyncBasedSession]
  11. _session_type = session_type
  12. def get_session_implement():
  13. global _session_type
  14. return _session_type
  15. def get_current_session() -> "AbstractSession":
  16. return _session_type.get_current_session()
  17. def get_current_task_id():
  18. return _session_type.get_current_task_id()
  19. def check_session_impl(session_type):
  20. def decorator(func):
  21. @wraps(func)
  22. def inner(*args, **kwargs):
  23. now_impl = get_session_implement()
  24. if now_impl is not session_type:
  25. func_name = getattr(func, '__name__', str(func))
  26. require = getattr(session_type, '__name__', str(session_type))
  27. now = getattr(now_impl, '__name__', str(now_impl))
  28. raise RuntimeError("Only can invoke `{func_name:s}` in {require:s} context."
  29. " You are now in {now:s} context".format(func_name=func_name, require=require,
  30. now=now))
  31. return func(*args, **kwargs)
  32. return inner
  33. return decorator
  34. @check_session_impl(AsyncBasedSession)
  35. def run_async(coro_obj):
  36. """异步运行协程对象,协程中依然可以调用 PyWebIO 交互函数。 仅能在 AsyncBasedSession 会话上下文中调用
  37. :param coro_obj: 协程对象
  38. """
  39. AsyncBasedSession.get_current_session().run_async(coro_obj)
  40. @check_session_impl(AsyncBasedSession)
  41. async def asyncio_coroutine(coro):
  42. """若会话线程和运行事件的线程不是同一个线程,需要用 asyncio_coroutine 来运行asyncio中的协程
  43. :param coro_obj: 协程对象
  44. """
  45. return await AsyncBasedSession.get_current_session().asyncio_coroutine(coro)
  46. @check_session_impl(ThreadBasedWebIOSession)
  47. def register_thread(thread: threading.Thread, as_daemon=True):
  48. """注册线程,以便在线程内调用 PyWebIO 交互函数。仅能在 ThreadBasedWebIOSession 会话上下文中调用
  49. :param threading.Thread thread: 线程对象
  50. :param bool as_daemon: 是否将线程设置为 daemon 线程. 默认为 True
  51. """
  52. return ThreadBasedWebIOSession.get_current_session().register_thread(thread, as_daemon=as_daemon)