from abc import ABC, abstractmethod
from typing import List, Optional
from olc.bean.tag_group import TagGroup
from olc.control.context.context import OlcContext
class BoxHandler(ABC):
"""
如果子类不涉及 I/O 等阻塞操作,只需要实现 do_*, 涉及阻塞操作需要做同步异步镜像实现
链路推进由 AbsBoxHandler 统一接管。
"""
@abstractmethod
def do_in_coming(
self, context: OlcContext, groups: List[TagGroup]
) -> Optional[List[TagGroup]]:
"""业务前置处理。
:return: None 沿用入参 groups;非 None 替换传给下游(GroupMatcherHandler 使用)
"""
@abstractmethod
def do_out_coming(self, context: OlcContext) -> None:
"""业务后置处理。"""
async def async_do_in_coming(
self, context: OlcContext, groups: List[TagGroup]
) -> Optional[List[TagGroup]]:
""" 默认由调用同步实现, 如有阻塞操作需要重写 """
return self.do_in_coming(context, groups)
async def async_do_out_coming(self, context: OlcContext) -> None:
""" 默认由调用同步实现, 如有阻塞操作需要重写 """
self.do_out_coming(context)
class AbsBoxHandler(BoxHandler, ABC):
"""链路推进基类 —— 统一接管 in_coming/out_coming,子类实现 do_*。
"""
stop_aware: bool = True
def __init__(
self,
next_handler: "AbsBoxHandler" = None,
private_handler: "AbsBoxHandler" = None,
):
self.next_handler = next_handler
self.private_handler = private_handler
def in_coming(self, context: OlcContext, groups: List[TagGroup]) -> None:
next_groups = groups
if not (self.stop_aware and context.stop):
ret = self.do_in_coming(context, groups)
if ret is not None:
next_groups = ret
self._next_in_coming(context, next_groups)
def out_coming(self, context: OlcContext) -> None:
self.do_out_coming(context)
self._next_out_coming(context)
async def async_in_coming(
self, context: OlcContext, groups: List[TagGroup]
) -> None:
next_groups = groups
if not (self.stop_aware and context.stop):
ret = await self.async_do_in_coming(context, groups)
if ret is not None:
next_groups = ret
await self._async_next_in_coming(context, next_groups)
async def async_out_coming(self, context: OlcContext) -> None:
await self.async_do_out_coming(context)
await self._async_next_out_coming(context)
def _next_in_coming(self, context: OlcContext, groups: List[TagGroup]):
if self.next_handler is not None:
self.next_handler.in_coming(context, groups)
def _next_out_coming(self, context: OlcContext):
if self.private_handler is not None:
self.private_handler.out_coming(context)
async def _async_next_in_coming(self, context: OlcContext, groups: List[TagGroup]):
if self.next_handler is not None:
await self.next_handler.async_in_coming(context, groups)
async def _async_next_out_coming(self, context: OlcContext):
if self.private_handler is not None:
await self.private_handler.async_out_coming(context)
def get_private(self) -> "AbsBoxHandler":
return self.private_handler
def get_next(self) -> "AbsBoxHandler":
return self.next_handler
def set_private(self, private_handler: "AbsBoxHandler"):
self.private_handler = private_handler
def set_next(self, next_handler: "AbsBoxHandler"):
self.next_handler = next_handler