ErisPulse 1.1.6__py3-none-any.whl → 1.1.8__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/__init__.py CHANGED
@@ -22,8 +22,6 @@ setattr(sdk, "adapter", adapter)
22
22
  setattr(sdk, "SendDSL", SendDSL)
23
23
  setattr(sdk, "BaseAdapter", BaseAdapter)
24
24
 
25
- env.load_env_file()
26
-
27
25
  # 注册 ErrorHook 并预注册常用错误类型
28
26
  raiserr.register("CaughtExternalError" , doc="捕获的非SDK抛出的异常")
29
27
  raiserr.register("InitError" , doc="SDK初始化错误")
@@ -34,6 +32,10 @@ raiserr.register("ModuleLoadError" , doc="模块加载错误")
34
32
 
35
33
  def init():
36
34
  try:
35
+ logger.info("[Init] SDK 正在初始化...")
36
+ env.create_env_file_if_not_exists()
37
+ env.load_env_file()
38
+
37
39
  sdkModulePath = os.path.join(os.path.dirname(__file__), "modules")
38
40
 
39
41
  if not os.path.exists(sdkModulePath):
ErisPulse/adapter.py CHANGED
@@ -10,8 +10,13 @@ class SendDSLBase:
10
10
  self._adapter = adapter
11
11
  self._target_type = target_type
12
12
  self._target_id = target_id
13
+ self._target_to = target_id
14
+
15
+ def To(self, target_type: str = None, target_id: str = None) -> 'SendDSL':
16
+ if target_id is None and target_type is not None:
17
+ target_id = target_type
18
+ target_type = None
13
19
 
14
- def To(self, target_type: str, target_id: str) -> 'SendDSL':
15
20
  return self.__class__(self._adapter, target_type, target_id)
16
21
 
17
22
  def __getattr__(self, name: str):
@@ -83,60 +88,79 @@ class AdapterManager:
83
88
  def __init__(self):
84
89
  self._adapters: Dict[str, BaseAdapter] = {}
85
90
  self._adapter_instances: Dict[Type[BaseAdapter], BaseAdapter] = {}
91
+ self._platform_to_instance: Dict[str, BaseAdapter] = {}
86
92
  self._started_instances: Set[BaseAdapter] = set()
93
+
87
94
  def register(self, platform: str, adapter_class: Type[BaseAdapter]) -> bool:
88
95
  if not issubclass(adapter_class, BaseAdapter):
89
96
  raise TypeError("适配器必须继承自BaseAdapter")
90
97
  from . import sdk
91
98
 
99
+ # 如果该类已经创建过实例,复用
92
100
  if adapter_class in self._adapter_instances:
93
- self._adapters[platform] = self._adapter_instances[adapter_class]
101
+ instance = self._adapter_instances[adapter_class]
94
102
  else:
95
103
  instance = adapter_class(sdk)
96
- self._adapters[platform] = instance
97
104
  self._adapter_instances[adapter_class] = instance
98
105
 
106
+ # 注册平台名,并统一映射到该实例
107
+ self._adapters[platform] = instance
108
+ self._platform_to_instance[platform] = instance
109
+
99
110
  return True
100
111
 
101
112
  async def startup(self, platforms: List[str] = None):
102
113
  if platforms is None:
103
114
  platforms = list(self._adapters.keys())
104
115
 
116
+ # 已经被调度过的 adapter 实例集合(防止重复调度)
117
+ scheduled_adapters = set()
118
+
105
119
  for platform in platforms:
106
120
  if platform not in self._adapters:
107
121
  raise ValueError(f"平台 {platform} 未注册")
108
122
  adapter = self._adapters[platform]
109
123
 
110
- # 如果该实例已经被启动过,跳过
111
- if adapter in self._started_instances:
124
+ # 如果该实例已经被启动或已调度,跳过
125
+ if adapter in self._started_instances or adapter in scheduled_adapters:
112
126
  continue
113
127
 
114
- self._started_instances.add(adapter)
128
+ # 加入调度队列
129
+ scheduled_adapters.add(adapter)
115
130
  asyncio.create_task(self._run_adapter(adapter, platform))
116
131
 
117
132
  async def _run_adapter(self, adapter: BaseAdapter, platform: str):
118
133
  from . import sdk
119
134
  retry_count = 0
120
135
  max_retry = 3
121
- while retry_count < max_retry:
122
- try:
123
- await adapter.start()
124
- sdk.logger.debug(f"尝试启动适配器 {platform},实例ID: {id(adapter)}")
125
- if adapter in self._started_instances:
126
- sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已启动,跳过")
127
- break
128
- except Exception as e:
129
- retry_count += 1
130
- sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
131
- try:
132
- await adapter.shutdown()
133
- except Exception as stop_err:
134
- sdk.logger.warning(f"停止适配器失败: {stop_err}")
135
136
 
136
- if retry_count >= max_retry:
137
- sdk.logger.critical(f"平台 {platform} 达到最大重试次数,放弃重启")
138
- sdk.raiserr.AdapterStartFailedError(f"平台 {platform} 适配器无法重写启动: {e}")
137
+ # 加锁防止并发启动
138
+ if not getattr(adapter, "_starting_lock", None):
139
+ adapter._starting_lock = asyncio.Lock()
140
+
141
+ async with adapter._starting_lock:
142
+ # 再次确认是否已经被启动
143
+ if adapter in self._started_instances:
144
+ sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已被其他协程启动,跳过")
145
+ return
139
146
 
147
+ while retry_count < max_retry:
148
+ try:
149
+ await adapter.start()
150
+ self._started_instances.add(adapter)
151
+ sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已启动")
152
+ break
153
+ except Exception as e:
154
+ retry_count += 1
155
+ sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
156
+ try:
157
+ await adapter.shutdown()
158
+ except Exception as stop_err:
159
+ sdk.logger.warning(f"停止适配器失败: {stop_err}")
160
+
161
+ if retry_count >= max_retry:
162
+ sdk.logger.critical(f"平台 {platform} 达到最大重试次数,放弃重启")
163
+ raise sdk.raiserr.AdapterStartFailedError(f"平台 {platform} 适配器无法重写启动: {e}")
140
164
  async def shutdown(self):
141
165
  for adapter in self._adapters.values():
142
166
  await adapter.shutdown()
ErisPulse/db.py CHANGED
@@ -16,7 +16,6 @@ class EnvManager:
16
16
  def __init__(self):
17
17
  if not hasattr(self, "_initialized"):
18
18
  self._init_db()
19
- self._create_env_file_if_not_exists()
20
19
  self._initialized = True
21
20
 
22
21
  def _init_db(self):
@@ -90,7 +89,7 @@ class EnvManager:
90
89
  if not key.startswith("__") and isinstance(value, (dict, list, str, int, float, bool)):
91
90
  self.set(key, value)
92
91
 
93
- def _create_env_file_if_not_exists(self):
92
+ def create_env_file_if_not_exists(self):
94
93
  env_file = Path("env.py")
95
94
  if not env_file.exists():
96
95
  content = '''# env.py
@@ -122,7 +121,7 @@ from ErisPulse import sdk
122
121
  try:
123
122
  return self.get(key)
124
123
  except KeyError:
125
- from . import sdk
126
- sdk.logger.error(f"配置项 {key} 不存在")
124
+ from .logger import logger
125
+ logger.error(f"配置项 {key} 不存在")
127
126
 
128
127
  env = EnvManager()
ErisPulse/logger.py CHANGED
@@ -148,5 +148,8 @@ class Logger:
148
148
  if self._get_effective_level(caller_module) <= logging.CRITICAL:
149
149
  self._save_in_memory(caller_module, msg)
150
150
  self._logger.critical(f"[{caller_module}] {msg}", *args, **kwargs)
151
+ from .raiserr import raiserr
152
+ raiserr.register("CriticalError", doc="发生致命错误")
153
+ raiserr.CriticalError(f"程序发生致命错误:{msg}", exit=True)
151
154
 
152
155
  logger = Logger()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ErisPulse
3
- Version: 1.1.6
3
+ Version: 1.1.8
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
@@ -0,0 +1,13 @@
1
+ ErisPulse/__init__.py,sha256=wNfAnZu0-jFzCLyQhfiXvj7lb0DxSLmRCBUowxUYJW0,7783
2
+ ErisPulse/__main__.py,sha256=-UdhsYP_X7EagomCjo73Y_qQdXwtMbDS5KoOSrI-OcU,32181
3
+ ErisPulse/adapter.py,sha256=u7XdJxIEHxGRh4RXwTX-vv1R1_oP0M6ZJBehe3rKi0I,6807
4
+ ErisPulse/db.py,sha256=OIndsysBOUfSyGMhKs-YVYj9dv5D92YIAltM0ZmwrkA,4379
5
+ ErisPulse/logger.py,sha256=sMA1mUZvwJ8wHwdyCrgIf_VRICv_uBCkx3tmd1stF3E,6094
6
+ ErisPulse/mods.py,sha256=M9XQWUQYNZ11m845hxbewBAauWXnysy-aOdLwb5xy_M,3312
7
+ ErisPulse/raiserr.py,sha256=z8BigWkVrBE9dD_dJa5np2YYREwdugyWXKE4_-LEO_Q,2616
8
+ ErisPulse/util.py,sha256=b9TqyRZKkpclN2fkHmWqBl3lnBMnUbucMvKvbqD5Ws8,2541
9
+ erispulse-1.1.8.dist-info/METADATA,sha256=UnKdj5QcnPTnmW0zRHWo2mxUME2CjJSM9ffcB1UUQNM,2282
10
+ erispulse-1.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ erispulse-1.1.8.dist-info/entry_points.txt,sha256=AjKvOdYR7QGXVpEJhjUYUwV2JluE4lm9vNbknC3hjOM,155
12
+ erispulse-1.1.8.dist-info/top_level.txt,sha256=Lm_qtkVvNJR8_dXh_qEDdl_12cZGpic-i4HUlVVUMZc,10
13
+ erispulse-1.1.8.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- ErisPulse/__init__.py,sha256=ZQlAumhGUM3skHfBRwSbbP_koy3FJaHiotVh-fD7YYc,7678
2
- ErisPulse/__main__.py,sha256=-UdhsYP_X7EagomCjo73Y_qQdXwtMbDS5KoOSrI-OcU,32181
3
- ErisPulse/adapter.py,sha256=cpynhF4HSSTUdPKlkXnGFf4RCfjzBmXxdXDm3K0M9Hw,5848
4
- ErisPulse/db.py,sha256=cd2AUfm-ZPzXlU8PLKK23QGd6VF0eSgYQl9dyRRpl_Y,4425
5
- ErisPulse/logger.py,sha256=HIQMYD75K-PL4IETMlm7V6Eyg0ussZ11_riEw5E5a08,5899
6
- ErisPulse/mods.py,sha256=M9XQWUQYNZ11m845hxbewBAauWXnysy-aOdLwb5xy_M,3312
7
- ErisPulse/raiserr.py,sha256=z8BigWkVrBE9dD_dJa5np2YYREwdugyWXKE4_-LEO_Q,2616
8
- ErisPulse/util.py,sha256=b9TqyRZKkpclN2fkHmWqBl3lnBMnUbucMvKvbqD5Ws8,2541
9
- erispulse-1.1.6.dist-info/METADATA,sha256=KQ1UD2ORHTkr4dr1LcshMQ2DZVrrpe96f-AzjxDucTI,2282
10
- erispulse-1.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- erispulse-1.1.6.dist-info/entry_points.txt,sha256=AjKvOdYR7QGXVpEJhjUYUwV2JluE4lm9vNbknC3hjOM,155
12
- erispulse-1.1.6.dist-info/top_level.txt,sha256=Lm_qtkVvNJR8_dXh_qEDdl_12cZGpic-i4HUlVVUMZc,10
13
- erispulse-1.1.6.dist-info/RECORD,,