ErisPulse 1.1.4__py3-none-any.whl → 1.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ErisPulse/adapter.py +53 -17
- {erispulse-1.1.4.dist-info → erispulse-1.1.7.dist-info}/METADATA +1 -1
- {erispulse-1.1.4.dist-info → erispulse-1.1.7.dist-info}/RECORD +6 -6
- {erispulse-1.1.4.dist-info → erispulse-1.1.7.dist-info}/WHEEL +0 -0
- {erispulse-1.1.4.dist-info → erispulse-1.1.7.dist-info}/entry_points.txt +0 -0
- {erispulse-1.1.4.dist-info → erispulse-1.1.7.dist-info}/top_level.txt +0 -0
ErisPulse/adapter.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import asyncio
|
|
3
|
-
from typing import Callable, Any, Dict, List, Type, Optional
|
|
3
|
+
from typing import Callable, Any, Dict, List, Type, Optional, Set
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
|
|
6
6
|
|
|
@@ -82,44 +82,80 @@ class BaseAdapter:
|
|
|
82
82
|
class AdapterManager:
|
|
83
83
|
def __init__(self):
|
|
84
84
|
self._adapters: Dict[str, BaseAdapter] = {}
|
|
85
|
+
self._adapter_instances: Dict[Type[BaseAdapter], BaseAdapter] = {}
|
|
86
|
+
self._platform_to_instance: Dict[str, BaseAdapter] = {}
|
|
87
|
+
self._started_instances: Set[BaseAdapter] = set()
|
|
85
88
|
|
|
86
89
|
def register(self, platform: str, adapter_class: Type[BaseAdapter]) -> bool:
|
|
87
90
|
if not issubclass(adapter_class, BaseAdapter):
|
|
88
91
|
raise TypeError("适配器必须继承自BaseAdapter")
|
|
89
92
|
from . import sdk
|
|
90
|
-
|
|
93
|
+
|
|
94
|
+
# 如果该类已经创建过实例,复用
|
|
95
|
+
if adapter_class in self._adapter_instances:
|
|
96
|
+
instance = self._adapter_instances[adapter_class]
|
|
97
|
+
else:
|
|
98
|
+
instance = adapter_class(sdk)
|
|
99
|
+
self._adapter_instances[adapter_class] = instance
|
|
100
|
+
|
|
101
|
+
# 注册平台名,并统一映射到该实例
|
|
102
|
+
self._adapters[platform] = instance
|
|
103
|
+
self._platform_to_instance[platform] = instance
|
|
104
|
+
|
|
91
105
|
return True
|
|
92
106
|
|
|
93
107
|
async def startup(self, platforms: List[str] = None):
|
|
94
108
|
if platforms is None:
|
|
95
|
-
platforms = self._adapters.keys()
|
|
109
|
+
platforms = list(self._adapters.keys())
|
|
110
|
+
|
|
111
|
+
# 已经被调度过的 adapter 实例集合(防止重复调度)
|
|
112
|
+
scheduled_adapters = set()
|
|
96
113
|
|
|
97
114
|
for platform in platforms:
|
|
98
115
|
if platform not in self._adapters:
|
|
99
116
|
raise ValueError(f"平台 {platform} 未注册")
|
|
100
117
|
adapter = self._adapters[platform]
|
|
118
|
+
|
|
119
|
+
# 如果该实例已经被启动或已调度,跳过
|
|
120
|
+
if adapter in self._started_instances or adapter in scheduled_adapters:
|
|
121
|
+
continue
|
|
122
|
+
|
|
123
|
+
# 加入调度队列
|
|
124
|
+
scheduled_adapters.add(adapter)
|
|
101
125
|
asyncio.create_task(self._run_adapter(adapter, platform))
|
|
102
126
|
|
|
103
127
|
async def _run_adapter(self, adapter: BaseAdapter, platform: str):
|
|
104
128
|
from . import sdk
|
|
105
129
|
retry_count = 0
|
|
106
130
|
max_retry = 3
|
|
107
|
-
while retry_count < max_retry:
|
|
108
|
-
try:
|
|
109
|
-
await adapter.start()
|
|
110
|
-
break
|
|
111
|
-
except Exception as e:
|
|
112
|
-
retry_count += 1
|
|
113
|
-
sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
|
|
114
|
-
try:
|
|
115
|
-
await adapter.shutdown()
|
|
116
|
-
except Exception as stop_err:
|
|
117
|
-
sdk.logger.warning(f"停止适配器失败: {stop_err}")
|
|
118
131
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
132
|
+
# 加锁防止并发启动
|
|
133
|
+
if not getattr(adapter, "_starting_lock", None):
|
|
134
|
+
adapter._starting_lock = asyncio.Lock()
|
|
122
135
|
|
|
136
|
+
async with adapter._starting_lock:
|
|
137
|
+
# 再次确认是否已经被启动
|
|
138
|
+
if adapter in self._started_instances:
|
|
139
|
+
sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已被其他协程启动,跳过")
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
while retry_count < max_retry:
|
|
143
|
+
try:
|
|
144
|
+
await adapter.start()
|
|
145
|
+
self._started_instances.add(adapter)
|
|
146
|
+
sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已启动")
|
|
147
|
+
break
|
|
148
|
+
except Exception as e:
|
|
149
|
+
retry_count += 1
|
|
150
|
+
sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
|
|
151
|
+
try:
|
|
152
|
+
await adapter.shutdown()
|
|
153
|
+
except Exception as stop_err:
|
|
154
|
+
sdk.logger.warning(f"停止适配器失败: {stop_err}")
|
|
155
|
+
|
|
156
|
+
if retry_count >= max_retry:
|
|
157
|
+
sdk.logger.critical(f"平台 {platform} 达到最大重试次数,放弃重启")
|
|
158
|
+
raise sdk.raiserr.AdapterStartFailedError(f"平台 {platform} 适配器无法重写启动: {e}")
|
|
123
159
|
async def shutdown(self):
|
|
124
160
|
for adapter in self._adapters.values():
|
|
125
161
|
await adapter.shutdown()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.7
|
|
4
4
|
Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
|
|
5
5
|
Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>, runoneall <runoobsteve@gmail.com>
|
|
6
6
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
ErisPulse/__init__.py,sha256=ZQlAumhGUM3skHfBRwSbbP_koy3FJaHiotVh-fD7YYc,7678
|
|
2
2
|
ErisPulse/__main__.py,sha256=-UdhsYP_X7EagomCjo73Y_qQdXwtMbDS5KoOSrI-OcU,32181
|
|
3
|
-
ErisPulse/adapter.py,sha256=
|
|
3
|
+
ErisPulse/adapter.py,sha256=aPdTx4FbB32PckT6CjhoCd0r2JyT_v3TkR-3STsAR-E,6631
|
|
4
4
|
ErisPulse/db.py,sha256=cd2AUfm-ZPzXlU8PLKK23QGd6VF0eSgYQl9dyRRpl_Y,4425
|
|
5
5
|
ErisPulse/logger.py,sha256=HIQMYD75K-PL4IETMlm7V6Eyg0ussZ11_riEw5E5a08,5899
|
|
6
6
|
ErisPulse/mods.py,sha256=M9XQWUQYNZ11m845hxbewBAauWXnysy-aOdLwb5xy_M,3312
|
|
7
7
|
ErisPulse/raiserr.py,sha256=z8BigWkVrBE9dD_dJa5np2YYREwdugyWXKE4_-LEO_Q,2616
|
|
8
8
|
ErisPulse/util.py,sha256=b9TqyRZKkpclN2fkHmWqBl3lnBMnUbucMvKvbqD5Ws8,2541
|
|
9
|
-
erispulse-1.1.
|
|
10
|
-
erispulse-1.1.
|
|
11
|
-
erispulse-1.1.
|
|
12
|
-
erispulse-1.1.
|
|
13
|
-
erispulse-1.1.
|
|
9
|
+
erispulse-1.1.7.dist-info/METADATA,sha256=PXek2AcafeVqLIjLz0Ldb4Bx7-iDeGILtOXDxPFMLAw,2282
|
|
10
|
+
erispulse-1.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
erispulse-1.1.7.dist-info/entry_points.txt,sha256=AjKvOdYR7QGXVpEJhjUYUwV2JluE4lm9vNbknC3hjOM,155
|
|
12
|
+
erispulse-1.1.7.dist-info/top_level.txt,sha256=Lm_qtkVvNJR8_dXh_qEDdl_12cZGpic-i4HUlVVUMZc,10
|
|
13
|
+
erispulse-1.1.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|