소스 검색

rename AsyncBasedSession->CoroutineBasedSession、ThreadBasedWebIOSession->ThreadBasedSession

wangweimin 5 년 전
부모
커밋
0a2b764c53

+ 1 - 1
pywebio/__init__.py

@@ -13,7 +13,7 @@ from . import input
 from . import output
 from .session import (
     set_session_implement, run_async, run_asyncio_coroutine, register_thread,
-    ThreadBasedWebIOSession, AsyncBasedSession
+    ThreadBasedSession, CoroutineBasedSession
 )
 from .exceptions import SessionException, SessionClosedException, SessionNotFoundException
 from .utils import STATIC_PATH

+ 2 - 2
pywebio/demos/zh/overview.py

@@ -6,7 +6,7 @@ import asyncio
 from datetime import datetime
 from functools import partial
 
-from pywebio import start_server, run_async, set_session_implement, AsyncBasedSession
+from pywebio import start_server, run_async, set_session_implement, CoroutineBasedSession
 from pywebio.input import *
 from pywebio.output import *
 
@@ -388,5 +388,5 @@ if __name__ == '__main__':
     parser.add_argument('--port', type=int, default=0, help='server bind port')
     args = parser.parse_args()
 
-    set_session_implement(AsyncBasedSession)
+    set_session_implement(CoroutineBasedSession)
     start_server(feature_overview, host=args.host, port=args.port, auto_open_webbrowser=True)

+ 2 - 2
pywebio/io_ctrl.py

@@ -5,7 +5,7 @@
 """
 import logging
 
-from .session import get_session_implement, AsyncBasedSession, get_current_task_id, get_current_session
+from .session import get_session_implement, CoroutineBasedSession, get_current_task_id, get_current_session
 from .utils import run_as_function, to_coroutine
 from functools import wraps
 
@@ -21,7 +21,7 @@ def chose_impl(gen_func):
     @wraps(gen_func)
     def inner(*args, **kwargs):
         gen = gen_func(*args, **kwargs)
-        if get_session_implement() == AsyncBasedSession:
+        if get_session_implement() == CoroutineBasedSession:
             return to_coroutine(gen)
         else:
             return run_as_function(gen)

+ 5 - 3
pywebio/output.py

@@ -297,11 +297,13 @@ def put_buttons(buttons, onclick, small=False, anchor=None, before=None, after=N
     :param str anchor, before, after: 与 `put_text` 函数的同名参数含义一致
     :param callback_options: 回调函数的其他参数。根据选用的 session 实现有不同参数
 
-        AsyncBasedSession 实现
+        CoroutineBasedSession 实现
             * mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应当前按钮组的新点击事件,仅当 ``onclick`` 为协程函数时有效
 
-        ThreadBasedWebIOSession 实现
-            * serial_mode: 串行模式模式。若为 ``True`` ,则对于同一组件的点击事件,串行执行其回调函数
+        ThreadBasedSession 实现
+            * serial_mode: 串行模式模式。若为 ``True`` ,则对于同一组件的点击事件,串行执行其回调函数。
+            不开启 ``serial_mode`` 时,ThreadBasedSession 在新线程中执行回调函数。所以如果回调函数运行时间很短,
+            可以关闭 ``serial_mode`` 来提高性能。
     """
     assert not (before and after), "Parameter 'before' and 'after' cannot be specified at the same time"
     btns = _format_button(buttons)

+ 8 - 7
pywebio/platform/flask.py

@@ -27,12 +27,13 @@ from typing import Dict
 
 from flask import Flask, request, jsonify, send_from_directory
 
-from ..session import AsyncBasedSession, ThreadBasedWebIOSession, get_session_implement, AbstractSession, mark_server_started
+from ..session import CoroutineBasedSession, ThreadBasedSession, get_session_implement, AbstractSession, \
+    mark_server_started
 from ..utils import STATIC_PATH
 from ..utils import random_str, LRUDict
 
 # todo: use lock to avoid thread race condition
-_webio_sessions: Dict[str, AsyncBasedSession] = {}  # WebIOSessionID -> WebIOSession()
+_webio_sessions: Dict[str, CoroutineBasedSession] = {}  # WebIOSessionID -> WebIOSession()
 _webio_expire = LRUDict()  # WebIOSessionID -> last active timestamp
 
 DEFAULT_SESSION_EXPIRE_SECONDS = 60 * 60 * 4  # 超过4个小时会话不活跃则视为会话过期
@@ -82,10 +83,10 @@ def _webio_view(coro_func, session_expire_seconds):
     if 'webio-session-id' not in request.headers or not request.headers['webio-session-id']:  # start new WebIOSession
         set_header = True
         webio_session_id = random_str(24)
-        if get_session_implement() is AsyncBasedSession:
-            webio_session = AsyncBasedSession(coro_func)
+        if get_session_implement() is CoroutineBasedSession:
+            webio_session = CoroutineBasedSession(coro_func)
         else:
-            webio_session = ThreadBasedWebIOSession(coro_func)
+            webio_session = ThreadBasedSession(coro_func)
         _webio_sessions[webio_session_id] = webio_session
         _webio_expire[webio_session_id] = time.time()
     elif request.headers['webio-session-id'] not in _webio_sessions:  # WebIOSession deleted
@@ -134,7 +135,7 @@ def start_flask_server(coro_func, port=8080, host='localhost', disable_asyncio=F
     :param coro_func:
     :param port:
     :param host:
-    :param disable_asyncio: 禁用 asyncio 函数。仅在使用 AsyncBasedSession 会话实现中有效。
+    :param disable_asyncio: 禁用 asyncio 函数。仅在使用 CoroutineBasedSession 会话实现中有效。
         在Flask backend中使用asyncio需要单独开启一个线程来运行事件循环,
         若程序中没有使用到asyncio中的异步函数,可以开启此选项来避免不必要的资源浪费
     :param session_expire_seconds:
@@ -155,7 +156,7 @@ def start_flask_server(coro_func, port=8080, host='localhost', disable_asyncio=F
     def serve_static_file(static_file):
         return send_from_directory(STATIC_PATH, static_file)
 
-    if not disable_asyncio and get_session_implement() is AsyncBasedSession:
+    if not disable_asyncio and get_session_implement() is CoroutineBasedSession:
         threading.Thread(target=_setup_event_loop, daemon=True).start()
 
     app.run(host=host, port=port, debug=debug, **flask_options)

+ 11 - 10
pywebio/platform/tornado.py

@@ -9,7 +9,7 @@ import tornado.httpserver
 import tornado.ioloop
 import tornado.websocket
 from tornado.web import StaticFileHandler
-from ..session import AsyncBasedSession, ThreadBasedWebIOSession, get_session_implement, DesignatedThreadSession, \
+from ..session import CoroutineBasedSession, ThreadBasedSession, get_session_implement, DesignatedThreadSession, \
     mark_server_started
 from ..utils import get_free_port, wait_host_port, STATIC_PATH
 
@@ -26,7 +26,7 @@ def webio_handler(task_func):
             # Non-None enables compression with default options.
             return {}
 
-        def send_msg_to_client(self, session: AsyncBasedSession):
+        def send_msg_to_client(self, session: CoroutineBasedSession):
             for msg in session.get_task_messages():
                 self.write_message(json.dumps(msg))
 
@@ -36,13 +36,13 @@ def webio_handler(task_func):
 
             self._close_from_session_tag = False  # 是否从session中关闭连接
 
-            if get_session_implement() is AsyncBasedSession:
-                self.session = AsyncBasedSession(task_func, on_task_message=self.send_msg_to_client,
-                                                 on_session_close=self.close)
+            if get_session_implement() is CoroutineBasedSession:
+                self.session = CoroutineBasedSession(task_func, on_task_message=self.send_msg_to_client,
+                                                     on_session_close=self.close)
             else:
-                self.session = ThreadBasedWebIOSession(task_func, on_task_message=self.send_msg_to_client,
-                                                       on_session_close=self.close_from_session,
-                                                       loop=asyncio.get_event_loop())
+                self.session = ThreadBasedSession(task_func, on_task_message=self.send_msg_to_client,
+                                                  on_session_close=self.close_from_session,
+                                                  loop=asyncio.get_event_loop())
 
         def on_message(self, message):
             data = json.loads(message)
@@ -92,8 +92,8 @@ def start_server(target, port=0, host='', debug=False,
                  **tornado_app_settings):
     """Start a Tornado server to serve `target` function
 
-    :param target: task function. It's a coroutine function is use AsyncBasedSession or
-        a simple function is use ThreadBasedWebIOSession.
+    :param target: task function. It's a coroutine function is use CoroutineBasedSession or
+        a simple function is use ThreadBasedSession.
     :param port: server bind port. set ``0`` to find a free port number to use
     :param host: server bind host. ``host`` may be either an IP address or hostname.  If it's a hostname,
         the server will listen on all IP addresses associated with the name.
@@ -129,6 +129,7 @@ def start_server(target, port=0, host='', debug=False,
 
 
 def start_server_in_current_thread_session():
+    """启动 script mode 的server"""
     mark_server_started()
 
     websocket_conn_opened = threading.Event()

+ 12 - 12
pywebio/session/__init__.py

@@ -1,27 +1,28 @@
 import threading
 from functools import wraps
 
-from .asyncbased import AsyncBasedSession
+from .coroutinebased import CoroutineBasedSession
 from .base import AbstractSession
-from .threadbased import ThreadBasedWebIOSession, DesignatedThreadSession
+from .threadbased import ThreadBasedSession, DesignatedThreadSession
 from ..exceptions import SessionNotFoundException
 
-_session_type = ThreadBasedWebIOSession
+_session_type = ThreadBasedSession
 
-__all__ = ['set_session_implement', 'run_async', 'run_asyncio_coroutine', 'register_thread']
+__all__ = ['run_async', 'run_asyncio_coroutine', 'register_thread']
 
 _server_started = False
 
 
 def mark_server_started():
-    """标记服务端已经启动"""
+    """标记服务端已经启动. 仅用于PyWebIO内部使用"""
     global _server_started
     _server_started = True
 
 
 def set_session_implement(session_type):
+    """设置会话实现类. 仅用于PyWebIO内部使用"""
     global _session_type
-    assert session_type in [ThreadBasedWebIOSession, AsyncBasedSession, DesignatedThreadSession]
+    assert session_type in [ThreadBasedSession, CoroutineBasedSession, DesignatedThreadSession]
     _session_type = session_type
 
 
@@ -79,16 +80,16 @@ def check_session_impl(session_type):
     return decorator
 
 
-@check_session_impl(AsyncBasedSession)
+@check_session_impl(CoroutineBasedSession)
 def run_async(coro_obj):
-    """异步运行协程对象,协程中依然可以调用 PyWebIO 交互函数。 仅能在 AsyncBasedSession 会话上下文中调用
+    """异步运行协程对象,协程中依然可以调用 PyWebIO 交互函数。 仅能在 CoroutineBasedSession 会话上下文中调用
 
     :param coro_obj: 协程对象
     """
     get_current_session().run_async(coro_obj)
 
 
-@check_session_impl(AsyncBasedSession)
+@check_session_impl(CoroutineBasedSession)
 async def run_asyncio_coroutine(coro_obj):
     """若会话线程和运行事件的线程不是同一个线程,需要用 run_asyncio_coroutine 来运行asyncio中的协程
 
@@ -97,11 +98,10 @@ async def run_asyncio_coroutine(coro_obj):
     return await get_current_session().run_asyncio_coroutine(coro_obj)
 
 
-@check_session_impl(ThreadBasedWebIOSession)
+@check_session_impl(ThreadBasedSession)
 def register_thread(thread: threading.Thread, as_daemon=True):
-    """注册线程,以便在线程内调用 PyWebIO 交互函数。仅能在 ThreadBasedWebIOSession 会话上下文中调用
+    """注册线程,以便在线程内调用 PyWebIO 交互函数。仅能在 ThreadBasedSession 会话上下文中调用
 
     :param threading.Thread thread: 线程对象
-    :param bool as_daemon: 是否将线程设置为 daemon 线程. 默认为 True
     """
     return get_current_session().register_thread(thread, as_daemon=as_daemon)

+ 7 - 7
pywebio/session/asyncbased.py → pywebio/session/coroutinebased.py

@@ -28,7 +28,7 @@ class _context:
     current_task_id = None
 
 
-class AsyncBasedSession(AbstractSession):
+class CoroutineBasedSession(AbstractSession):
     """
     一个PyWebIO任务会话, 由不同的后端Backend创建并维护
 
@@ -41,7 +41,7 @@ class AsyncBasedSession(AbstractSession):
     """
 
     @staticmethod
-    def get_current_session() -> "AsyncBasedSession":
+    def get_current_session() -> "CoroutineBasedSession":
         if _context.current_session is None:
             raise SessionNotFoundException("No current found in context!")
         return _context.current_session
@@ -162,7 +162,7 @@ class AsyncBasedSession(AbstractSession):
         :param callback: 回调函数. 可以是普通函数或者协程函数. 函数签名为 ``callback(data)``.
         :param bool mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应同一组件的新点击事件,仅当 ``callback`` 为协程函数时有效
         :return str: 回调id.
-            AsyncBasedSession保证当收到前端发送的事件消息 ``{event: "callback",coro_id: 回调id, data:...}`` 时,
+            CoroutineBasedSession 保证当收到前端发送的事件消息 ``{event: "callback",coro_id: 回调id, data:...}`` 时,
             ``callback`` 回调函数被执行, 并传入事件消息中的 ``data`` 字段值作为参数
         """
 
@@ -179,7 +179,7 @@ class AsyncBasedSession(AbstractSession):
                     try:
                         callback(event['data'])
                     except:
-                        AsyncBasedSession.get_current_session().on_task_exception()
+                        AsyncCoroutineBasedSessionBasedSession.get_current_session().on_task_exception()
 
                 if coro is not None:
                     if mutex_mode:
@@ -187,9 +187,9 @@ class AsyncBasedSession(AbstractSession):
                     else:
                         self.run_async(coro)
 
-        callback_task = Task(callback_coro(), AsyncBasedSession.get_current_session())
+        callback_task = Task(callback_coro(), CoroutineBasedSession.get_current_session())
         callback_task.coro.send(None)  # 激活,Non't callback.step() ,导致嵌套调用step  todo 与inactive_coro_instances整合
-        AsyncBasedSession.get_current_session().coros[callback_task.coro_id] = callback_task
+        CoroutineBasedSession.get_current_session().coros[callback_task.coro_id] = callback_task
 
         return callback_task.coro_id
 
@@ -227,7 +227,7 @@ class Task:
 
         return '%s-%s' % (name, random_str(10))
 
-    def __init__(self, coro, session: AsyncBasedSession, on_coro_stop=None):
+    def __init__(self, coro, session: CoroutineBasedSession, on_coro_stop=None):
         self.session = session
         self.coro = coro
         self.coro_id = None

+ 10 - 10
pywebio/session/threadbased.py

@@ -17,20 +17,20 @@ logger = logging.getLogger(__name__)
 
 主任务线程退出后,连接关闭,但不会清理主任务线程产生的其他线程
 
-客户端连接关闭后,后端线程不会退出,但是再次调用
+客户端连接关闭后,后端线程不会退出,但是再次调用输入输出函数会引发异常
 todo: thread 重名
 """
 
 
 # todo 线程安全
-class ThreadBasedWebIOSession(AbstractSession):
+class ThreadBasedSession(AbstractSession):
     thread2session = {}  # thread_id -> session
 
     event_mq_maxsize = 100
     callback_mq_maxsize = 100
 
     @classmethod
-    def get_current_session(cls) -> "ThreadBasedWebIOSession":
+    def get_current_session(cls) -> "ThreadBasedSession":
         curr = threading.current_thread().getName()
         session = cls.thread2session.get(curr)
         if session is None:
@@ -70,7 +70,7 @@ class ThreadBasedWebIOSession(AbstractSession):
 
     def _start_main_task(self, target):
         assert (not asyncio.iscoroutinefunction(target)) and (not inspect.isgeneratorfunction(target)), ValueError(
-            "In ThreadBasedWebIOSession.__init__, `target` must be a simple function, "
+            "In ThreadBasedSession.__init__, `target` must be a simple function, "
             "not coroutine function or generator function. ")
 
         def thread_task(target):
@@ -133,7 +133,7 @@ class ThreadBasedWebIOSession(AbstractSession):
         # Don't clean unhandled_task_msgs, it may not send to client
         # self.unhandled_task_msgs = []
         for t in self.threads:
-            del ThreadBasedWebIOSession.thread2session[t]
+            del ThreadBasedSession.thread2session[t]
             # pass
 
         if self.callback_mq is not None:  # 回调功能已经激活
@@ -168,7 +168,7 @@ class ThreadBasedWebIOSession(AbstractSession):
     def _activate_callback_env(self):
         """激活回调功能
 
-        ThreadBasedWebIOSession的回调实现原理是:创建一个单独的线程用于接收回调事件,进而调用相关的回调函数。
+        ThreadBasedSession 的回调实现原理是:创建一个单独的线程用于接收回调事件,进而调用相关的回调函数。
         当用户Task中并没有使用到回调功能时,不必开启此线程,可以节省资源
         """
 
@@ -197,7 +197,7 @@ class ThreadBasedWebIOSession(AbstractSession):
                 try:
                     callback(event['data'])
                 except:
-                    ThreadBasedWebIOSession.get_current_session().on_task_exception()
+                    ThreadBasedSession.get_current_session().on_task_exception()
 
             if mutex:
                 run(callback)
@@ -216,7 +216,7 @@ class ThreadBasedWebIOSession(AbstractSession):
         :param bool serial_mode: 串行模式模式。若为 ``True`` ,则对于同一组件的点击事件,串行执行其回调函数
         """
         assert (not asyncio.iscoroutinefunction(callback)) and (not inspect.isgeneratorfunction(callback)), ValueError(
-            "In ThreadBasedWebIOSession.register_callback, `callback` must be a simple function, "
+            "In ThreadBasedSession.register_callback, `callback` must be a simple function, "
             "not coroutine function or generator function. ")
 
         self._activate_callback_env()
@@ -225,7 +225,7 @@ class ThreadBasedWebIOSession(AbstractSession):
         return callback_id
 
     def register_thread(self, t: threading.Thread, as_daemon=True):
-        """注册线程,以便在线程内调用 pywebio 交互函数
+        """将线程注册到当前会话,以便在线程内调用 pywebio 交互函数
 
         :param threading.Thread thread: 线程对象
         :param bool as_daemon: 是否将线程设置为 daemon 线程. 默认为 True
@@ -239,7 +239,7 @@ class ThreadBasedWebIOSession(AbstractSession):
         self.event_mqs[tname] = event_mq
 
 
-class DesignatedThreadSession(ThreadBasedWebIOSession):
+class DesignatedThreadSession(ThreadBasedSession):
     """以指定进程为会话"""
 
     def __init__(self, thread, on_task_message=None, loop=None):