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 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
- self._adapters[platform] = adapter_class(sdk)
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
- if retry_count >= max_retry:
120
- sdk.logger.critical(f"平台 {platform} 达到最大重试次数,放弃重启")
121
- sdk.raiserr.AdapterStartFailedError(f"平台 {platform} 适配器无法重写启动: {e}")
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.4
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=9AaUrCNQ6UwN3rE7Tqdbl2mxIbOtiLQGcEm10mcKkEw,5017
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.4.dist-info/METADATA,sha256=5XD1haEr6A1WIr2jEyzDqO2dMlvctD5RGJpFdbN7hCE,2282
10
- erispulse-1.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- erispulse-1.1.4.dist-info/entry_points.txt,sha256=AjKvOdYR7QGXVpEJhjUYUwV2JluE4lm9vNbknC3hjOM,155
12
- erispulse-1.1.4.dist-info/top_level.txt,sha256=Lm_qtkVvNJR8_dXh_qEDdl_12cZGpic-i4HUlVVUMZc,10
13
- erispulse-1.1.4.dist-info/RECORD,,
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,,