ErisPulse 2.2.1.dev0__py3-none-any.whl → 2.3.0__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.
Files changed (36) hide show
  1. ErisPulse/Core/Bases/__init__.py +14 -0
  2. ErisPulse/Core/Bases/adapter.py +196 -0
  3. ErisPulse/Core/Bases/module.py +54 -0
  4. ErisPulse/Core/Event/__init__.py +14 -0
  5. ErisPulse/Core/Event/base.py +15 -2
  6. ErisPulse/Core/Event/command.py +21 -2
  7. ErisPulse/Core/Event/message.py +15 -0
  8. ErisPulse/Core/Event/meta.py +15 -0
  9. ErisPulse/Core/Event/notice.py +15 -0
  10. ErisPulse/Core/Event/request.py +16 -1
  11. ErisPulse/Core/__init__.py +38 -19
  12. ErisPulse/Core/{erispulse_config.py → _self_config.py} +27 -2
  13. ErisPulse/Core/adapter.py +374 -377
  14. ErisPulse/Core/config.py +137 -38
  15. ErisPulse/Core/exceptions.py +6 -1
  16. ErisPulse/Core/lifecycle.py +167 -0
  17. ErisPulse/Core/logger.py +97 -49
  18. ErisPulse/Core/module.py +279 -56
  19. ErisPulse/Core/router.py +112 -23
  20. ErisPulse/Core/storage.py +258 -77
  21. ErisPulse/Core/ux.py +635 -0
  22. ErisPulse/__init__.py +722 -244
  23. ErisPulse/__main__.py +1 -1999
  24. ErisPulse/utils/__init__.py +17 -0
  25. ErisPulse/utils/cli.py +1092 -0
  26. ErisPulse/utils/console.py +53 -0
  27. ErisPulse/utils/package_manager.py +845 -0
  28. ErisPulse/utils/reload_handler.py +111 -0
  29. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/METADATA +24 -6
  30. erispulse-2.3.0.dist-info/RECORD +34 -0
  31. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/WHEEL +1 -1
  32. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/licenses/LICENSE +1 -1
  33. ErisPulse/Core/env.py +0 -15
  34. ErisPulse/Core/module_registry.py +0 -227
  35. erispulse-2.2.1.dev0.dist-info/RECORD +0 -26
  36. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/entry_points.txt +0 -0
ErisPulse/__init__.py CHANGED
@@ -5,13 +5,14 @@ ErisPulse SDK 主模块
5
5
 
6
6
  {!--< tips >!--}
7
7
  1. 使用前请确保已正确安装所有依赖
8
- 2. 调用sdk.init()进行初始化
8
+ 2. 调用await sdk.init()进行初始化
9
9
  3. 模块加载采用懒加载机制
10
10
  {!--< /tips >!--}
11
11
  """
12
12
 
13
13
  import os
14
14
  import sys
15
+ import types
15
16
  import importlib
16
17
  import asyncio
17
18
  import inspect
@@ -20,16 +21,23 @@ from typing import Dict, List, Tuple, Type, Any
20
21
  from pathlib import Path
21
22
 
22
23
  # BaseModules: SDK核心模块
23
- from .Core import logger
24
- from .Core import storage
25
- from .Core import env
26
- from .Core import module_registry
27
- from .Core import adapter, AdapterFather, SendDSL
24
+ # 事件处理模块
25
+ from .Core import Event
26
+ # 基础设施
27
+ from .Core import lifecycle, logger, exceptions
28
+ # 存储和配置相关
29
+ from .Core import storage, env, config
30
+ # 适配器相关
31
+ from .Core import adapter, AdapterFather, BaseAdapter, SendDSL
32
+ # 模块相关
28
33
  from .Core import module
34
+ # 路由相关
29
35
  from .Core import router, adapter_server
30
- from .Core import exceptions
31
- from .Core import config
32
- from .Core import Event
36
+ # 用户体验相关
37
+ from .Core import ux, UXManager
38
+
39
+ # SDK统一对外接口
40
+ sdk = types.ModuleType('sdk')
33
41
 
34
42
  try:
35
43
  __version__ = importlib.metadata.version('ErisPulse')
@@ -37,31 +45,42 @@ except importlib.metadata.PackageNotFoundError:
37
45
  logger.critical("未找到ErisPulse版本信息,请检查是否正确安装ErisPulse")
38
46
  __author__ = "ErisPulse"
39
47
 
40
- sdk = sys.modules[__name__]
48
+ logger.debug("ErisPulse 正在挂载SDK核心模块...")
41
49
 
42
50
  BaseModules = {
43
- "Event": Event,
44
- "logger": logger,
45
- "config": config,
46
- "exceptions": exceptions,
47
- "storage": storage,
48
- "env": env,
49
- "module_registry": module_registry,
50
- "adapter": adapter,
51
- "module": module,
51
+ "Event" : Event,
52
+
53
+ "lifecycle" : lifecycle,
54
+ "logger" : logger,
55
+ "exceptions" : exceptions,
56
+
57
+ "storage" : storage,
58
+ "env" : env,
59
+ "config" : config,
60
+
61
+ "adapter" : adapter,
62
+ "AdapterFather" : AdapterFather,
63
+ "BaseAdapter" : BaseAdapter,
64
+ "SendDSL" : SendDSL,
65
+
66
+ "module" : module,
67
+
52
68
  "router": router,
53
69
  "adapter_server": adapter_server,
54
- "SendDSL": SendDSL,
55
- "AdapterFather": AdapterFather,
56
- "BaseAdapter": AdapterFather
70
+ "ux": ux,
71
+ "UXManager": UXManager,
57
72
  }
58
73
 
59
- asyncio_loop = asyncio.get_event_loop()
74
+ for module_name, moduleObj in BaseModules.items():
75
+ setattr(sdk, module_name, moduleObj)
76
+
77
+ logger.debug("ErisPulse 正在挂载loop循环器...")
60
78
 
79
+ # 设置默认loop循环捕捉器
80
+ asyncio_loop = asyncio.get_event_loop()
61
81
  exceptions.setup_async_loop(asyncio_loop)
62
82
 
63
- for module, moduleObj in BaseModules.items():
64
- setattr(sdk, module, moduleObj)
83
+ logger.debug("SDK核心模块挂载完毕")
65
84
 
66
85
  class LazyModule:
67
86
  """
@@ -72,6 +91,7 @@ class LazyModule:
72
91
  {!--< tips >!--}
73
92
  1. 模块的实际实例化会在第一次属性访问时进行
74
93
  2. 依赖模块会在被使用时自动初始化
94
+ 3. 对于继承自 BaseModule 的模块,会自动调用生命周期方法
75
95
  {!--< /tips >!--}
76
96
  """
77
97
 
@@ -84,110 +104,305 @@ class LazyModule:
84
104
  :param sdk_ref: Any SDK引用
85
105
  :param module_info: Dict[str, Any] 模块信息字典
86
106
  """
87
- self._module_name = module_name
88
- self._module_class = module_class
89
- self._sdk_ref = sdk_ref
90
- self._module_info = module_info
91
- self._instance = None
92
- self._initialized = False
107
+ # 使用object.__setattr__避免触发自定义的__setattr__
108
+ object.__setattr__(self, '_module_name', module_name)
109
+ object.__setattr__(self, '_module_class', module_class)
110
+ object.__setattr__(self, '_sdk_ref', sdk_ref)
111
+ object.__setattr__(self, '_module_info', module_info)
112
+ object.__setattr__(self, '_instance', None)
113
+ object.__setattr__(self, '_initialized', False)
114
+ object.__setattr__(self, '_is_base_module', module_info.get("meta", {}).get("is_base_module", False))
93
115
 
94
- def _initialize(self):
116
+ async def _initialize(self):
95
117
  """
96
118
  实际初始化模块
97
119
 
98
120
  :raises LazyLoadError: 当模块初始化失败时抛出
99
121
  """
122
+ # 避免重复初始化
123
+ if object.__getattribute__(self, '_initialized'):
124
+ return
125
+
126
+ logger.debug(f"正在初始化懒加载模块 {object.__getattribute__(self, '_module_name')}...")
127
+
100
128
  try:
101
129
  # 获取类的__init__参数信息
102
- init_signature = inspect.signature(self._module_class.__init__)
130
+ logger.debug(f"正在获取模块 {object.__getattribute__(self, '_module_name')} 的 __init__ 参数信息...")
131
+ init_signature = inspect.signature(object.__getattribute__(self, '_module_class').__init__)
103
132
  params = init_signature.parameters
104
133
 
105
134
  # 根据参数决定是否传入sdk
106
135
  if 'sdk' in params:
107
- self._instance = self._module_class(self._sdk_ref)
136
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 需要传入 sdk 参数")
137
+ instance = object.__getattribute__(self, '_module_class')(object.__getattribute__(self, '_sdk_ref'))
108
138
  else:
109
- self._instance = self._module_class()
139
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 不需要传入 sdk 参数")
140
+ instance = object.__getattribute__(self, '_module_class')()
141
+
142
+ logger.debug(f"正在设置模块 {object.__getattribute__(self, '_module_name')} 的 moduleInfo 属性...")
143
+ setattr(instance, "moduleInfo", object.__getattribute__(self, '_module_info'))
144
+
145
+ # 使用object.__setattr__避免触发自定义的__setattr__
146
+ object.__setattr__(self, '_instance', instance)
147
+ object.__setattr__(self, '_initialized', True)
148
+
149
+ # 如果是 BaseModule 子类,在初始化后调用 on_load 方法
150
+ if object.__getattribute__(self, '_is_base_module'):
151
+ logger.debug(f"正在调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法...")
152
+
153
+ try:
154
+ await module.load(object.__getattribute__(self, '_module_name'))
155
+ except Exception as e:
156
+ logger.error(f"调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法时出错: {e}")
157
+
158
+ await lifecycle.submit_event(
159
+ "module.init",
160
+ msg=f"模块 {object.__getattribute__(self, '_module_name')} 初始化完毕",
161
+ data={
162
+ "module_name": object.__getattribute__(self, '_module_name'),
163
+ "success": True,
164
+ }
165
+ )
166
+ logger.debug(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 初始化完成")
110
167
 
111
- setattr(self._instance, "moduleInfo", self._module_info)
112
- self._initialized = True
113
- logger.debug(f"模块 {self._module_name} 初始化完成")
114
168
  except Exception as e:
115
- logger.error(f"模块 {self._module_name} 初始化失败: {e}")
116
- raise
169
+ await lifecycle.submit_event(
170
+ "module.init",
171
+ msg=f"模块初始化失败: {e}",
172
+ data={
173
+ "module_name": object.__getattribute__(self, '_module_name'),
174
+ "success": False,
175
+ }
176
+ )
177
+ logger.error(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 初始化失败: {e}")
178
+ raise e
117
179
 
118
- def __getattr__(self, name: str) -> Any:
180
+ def _initialize_sync(self):
119
181
  """
120
- 属性访问时触发初始化
182
+ 同步初始化模块,用于在异步上下文中进行同步调用
121
183
 
122
- :param name: str 要访问的属性名
123
- :return: Any 模块属性值
184
+ :raises LazyLoadError: 当模块初始化失败时抛出
124
185
  """
125
- if not self._initialized:
126
- self._initialize()
127
- return getattr(self._instance, name)
186
+ # 避免重复初始化
187
+ if object.__getattribute__(self, '_initialized'):
188
+ return
189
+
190
+ logger.debug(f"正在同步初始化懒加载模块 {object.__getattribute__(self, '_module_name')}...")
191
+
192
+ try:
193
+ # 获取类的__init__参数信息
194
+ logger.debug(f"正在获取模块 {object.__getattribute__(self, '_module_name')} 的 __init__ 参数信息...")
195
+ init_signature = inspect.signature(object.__getattribute__(self, '_module_class').__init__)
196
+ params = init_signature.parameters
197
+
198
+ # 根据参数决定是否传入sdk
199
+ if 'sdk' in params:
200
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 需要传入 sdk 参数")
201
+ instance = object.__getattribute__(self, '_module_class')(object.__getattribute__(self, '_sdk_ref'))
202
+ else:
203
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 不需要传入 sdk 参数")
204
+ instance = object.__getattribute__(self, '_module_class')()
205
+
206
+ logger.debug(f"正在设置模块 {object.__getattribute__(self, '_module_name')} 的 moduleInfo 属性...")
207
+ setattr(instance, "moduleInfo", object.__getattribute__(self, '_module_info'))
208
+
209
+ # 使用object.__setattr__避免触发自定义的__setattr__
210
+ object.__setattr__(self, '_instance', instance)
211
+ object.__setattr__(self, '_initialized', True)
212
+ object.__setattr__(self, '_needs_async_init', False) # 确保清除异步初始化标志
213
+
214
+ # 注意:在同步初始化中,我们不能调用异步的 module.load 和 lifecycle.submit_event
215
+ # 这些将在异步上下文中延迟处理
216
+
217
+ logger.debug(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 同步初始化完成")
218
+
219
+ except Exception as e:
220
+ logger.error(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 同步初始化失败: {e}")
221
+ raise e
128
222
 
129
- def __call__(self, *args, **kwargs) -> Any:
223
+ async def _complete_async_init(self):
130
224
  """
131
- 调用时触发初始化
225
+ 完成异步初始化部分,用于同步初始化后的异步处理
132
226
 
133
- :param args: 位置参数
134
- :param kwargs: 关键字参数
135
- :return: Any 模块调用结果
227
+ 这个方法用于处理 module.load 和事件提交等异步操作
136
228
  """
137
- if not self._initialized:
138
- self._initialize()
139
- return self._instance(*args, **kwargs)
229
+ if not object.__getattribute__(self, '_initialized'):
230
+ return
231
+
232
+ try:
233
+ # 如果是 BaseModule 子类,在初始化后调用 on_load 方法
234
+ if object.__getattribute__(self, '_is_base_module'):
235
+ logger.debug(f"正在异步调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法...")
236
+
237
+ try:
238
+ await module.load(object.__getattribute__(self, '_module_name'))
239
+ except Exception as e:
240
+ logger.error(f"异步调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法时出错: {e}")
241
+
242
+ await lifecycle.submit_event(
243
+ "module.init",
244
+ msg=f"模块 {object.__getattribute__(self, '_module_name')} 初始化完毕",
245
+ data={
246
+ "module_name": object.__getattribute__(self, '_module_name'),
247
+ "success": True,
248
+ }
249
+ )
250
+ logger.debug(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 异步初始化部分完成")
251
+ except Exception as e:
252
+ await lifecycle.submit_event(
253
+ "module.init",
254
+ msg=f"模块初始化失败: {e}",
255
+ data={
256
+ "module_name": object.__getattribute__(self, '_module_name'),
257
+ "success": False,
258
+ }
259
+ )
260
+ logger.error(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 异步初始化部分失败: {e}")
140
261
 
141
- def __bool__(self) -> bool:
262
+ def _ensure_initialized(self) -> None:
142
263
  """
143
- 判断模块布尔值时触发初始化
144
-
145
- :return: bool 模块布尔值
264
+ 确保模块已初始化
265
+
266
+ :raises LazyLoadError: 当模块未初始化时抛出
146
267
  """
147
- if not self._initialized:
148
- self._initialize()
149
- return bool(self._instance)
268
+ if not object.__getattribute__(self, '_initialized'):
269
+ # 检查当前是否在异步上下文中
270
+ try:
271
+ loop = asyncio.get_running_loop()
272
+ # 如果在异步上下文中,我们需要检查模块初始化方法是否需要异步
273
+ init_method = getattr(object.__getattribute__(self, '_module_class'), '__init__', None)
274
+
275
+ # 检查__init__方法是否是协程函数
276
+ if asyncio.iscoroutinefunction(init_method):
277
+ # 对于需要异步初始化的模块,我们只能设置一个标志,提示需要异步初始化
278
+ object.__setattr__(self, '_needs_async_init', True)
279
+ logger.warning(f"模块 {object.__getattribute__(self, '_module_name')} 需要异步初始化,请在异步上下文中调用")
280
+ return
281
+ else:
282
+ # 对于同步初始化的模块,使用同步初始化方式
283
+ self._initialize_sync()
284
+
285
+ # 异步处理需要在初始化后完成的事件
286
+ if object.__getattribute__(self, '_is_base_module'):
287
+ # 调度异步任务来处理 module.load 和事件提交
288
+ try:
289
+ loop = asyncio.get_running_loop()
290
+ loop.create_task(self._complete_async_init())
291
+ except Exception as e:
292
+ logger.warning(f"无法调度异步初始化任务: {e}")
293
+ except RuntimeError:
294
+ # 没有运行中的事件循环,可以安全地创建新的事件循环
295
+ asyncio.run(self._initialize())
150
296
 
151
- def __str__(self) -> str:
297
+ def __getattr__(self, name: str) -> Any:
152
298
  """
153
- 转换为字符串时触发初始化
299
+ 属性访问时触发初始化
154
300
 
155
- :return: str 模块字符串表示
301
+ :param name: str 属性名
302
+ :return: Any 属性值
156
303
  """
157
- if not self._initialized:
158
- self._initialize()
159
- return str(self._instance)
160
- return str(self._instance)
304
+ logger.debug(f"正在访问懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性 {name}...")
305
+
306
+ # 检查是否需要异步初始化
307
+ if hasattr(self, '_needs_async_init') and object.__getattribute__(self, '_needs_async_init'):
308
+ raise RuntimeError(
309
+ f"模块 {object.__getattribute__(self, '_module_name')} 需要异步初始化,"
310
+ f"请使用 'await sdk.load_module(\"{object.__getattribute__(self, '_module_name')}\")' 来初始化模块"
311
+ )
312
+
313
+ self._ensure_initialized()
314
+ return getattr(object.__getattribute__(self, '_instance'), name)
161
315
 
162
- # 确保模块在被赋值给变量后仍然能正确工作
163
- def __getattribute__(self, name: str) -> Any:
164
- try:
165
- # 首先尝试获取常规属性
166
- return super().__getattribute__(name)
167
- except AttributeError:
168
- # 如果常规属性不存在,触发初始化
169
- if name != '_initialized' and not self._initialized:
170
- self._initialize()
171
- return getattr(self._instance, name)
172
- raise
316
+ def __setattr__(self, name: str, value: Any) -> None:
317
+ """
318
+ 属性设置
173
319
 
174
- def __copy__(self):
320
+ :param name: str 属性名
321
+ :param value: Any 属性值
175
322
  """
176
- 浅拷贝时返回自身,保持懒加载特性
323
+ logger.debug(f"正在设置懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性 {name}...")
177
324
 
178
- :return: self
325
+ # 特殊属性直接设置到包装器上
326
+ if name.startswith('_') or name in ('moduleInfo',):
327
+ object.__setattr__(self, name, value)
328
+ else:
329
+ # 其他属性在初始化前设置到包装器上,初始化后设置到实际模块实例上
330
+ if name == '_instance' or not hasattr(self, '_initialized') or not object.__getattribute__(self, '_initialized'):
331
+ object.__setattr__(self, name, value)
332
+ else:
333
+ setattr(object.__getattribute__(self, '_instance'), name, value)
334
+
335
+ def __delattr__(self, name: str) -> None:
336
+ """
337
+ 属性删除
338
+
339
+ :param name: str 属性名
179
340
  """
180
- return self
341
+ logger.debug(f"正在删除懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性 {name}...")
181
342
 
182
- def __deepcopy__(self, memo):
343
+ self._ensure_initialized()
344
+ delattr(object.__getattribute__(self, '_instance'), name)
345
+
346
+ def __getattribute__(self, name: str) -> Any:
183
347
  """
184
- 深拷贝时返回自身,保持懒加载特性
348
+ 属性访问,初始化后直接委托给实际实例
349
+
350
+ :param name: str 属性名
351
+ :return: Any 属性值
352
+ """
353
+ # 特殊属性直接从包装器获取
354
+ if name.startswith('_') or name in ('moduleInfo',):
355
+ return object.__getattribute__(self, name)
356
+
357
+ # 检查是否已初始化
358
+ try:
359
+ initialized = object.__getattribute__(self, '_initialized')
360
+ except AttributeError:
361
+ # 避免在初始化过程中访问_initialized时出现递归
362
+ return object.__getattribute__(self, name)
363
+
364
+ if not initialized:
365
+ # 确保初始化
366
+ self._ensure_initialized()
367
+ # 重新获取initialized状态
368
+ initialized = object.__getattribute__(self, '_initialized')
369
+
370
+ # 初始化后直接委托给实际实例
371
+ if initialized:
372
+ instance = object.__getattribute__(self, '_instance')
373
+ return getattr(instance, name)
374
+ else:
375
+ return object.__getattribute__(self, name)
376
+
377
+ def __dir__(self) -> List[str]:
378
+ """
379
+ 返回模块属性列表
380
+
381
+ :return: List[str] 属性列表
382
+ """
383
+ logger.debug(f"正在获取懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性列表...")
185
384
 
186
- :param memo: memo
187
- :return: self
385
+ self._ensure_initialized()
386
+ return dir(object.__getattribute__(self, '_instance'))
387
+
388
+ def __repr__(self) -> str:
389
+ """
390
+ 返回模块表示字符串
391
+
392
+ :return: str 表示字符串
188
393
  """
189
- return self
394
+ logger.debug(f"正在获取懒加载模块 {object.__getattribute__(self, '_module_name')} 的表示字符串...")
190
395
 
396
+ if object.__getattribute__(self, '_initialized'):
397
+ return repr(object.__getattribute__(self, '_instance'))
398
+ return f"<LazyModule {object.__getattribute__(self, '_module_name')} (not initialized)>"
399
+
400
+ # 代理所有其他魔术方法到实际模块实例
401
+ def __call__(self, *args, **kwargs):
402
+ """代理函数调用"""
403
+ self._ensure_initialized()
404
+ return object.__getattribute__(self, '_instance')(*args, **kwargs)
405
+
191
406
 
192
407
  class AdapterLoader:
193
408
  """
@@ -203,7 +418,7 @@ class AdapterLoader:
203
418
  """
204
419
 
205
420
  @staticmethod
206
- def load() -> Tuple[Dict[str, object], List[str], List[str]]:
421
+ async def load() -> Tuple[Dict[str, object], List[str], List[str]]:
207
422
  """
208
423
  从PyPI包entry-points加载适配器
209
424
 
@@ -218,27 +433,33 @@ class AdapterLoader:
218
433
  enabled_adapters = []
219
434
  disabled_adapters = []
220
435
 
436
+ logger.info("正在加载适配器entry-points...")
437
+
221
438
  try:
222
439
  # 加载适配器entry-points
440
+ logger.debug("正在获取适配器entry-points...")
223
441
  entry_points = importlib.metadata.entry_points()
224
442
  if hasattr(entry_points, 'select'):
225
443
  adapter_entries = entry_points.select(group='erispulse.adapter')
226
444
  else:
227
- adapter_entries = entry_points.get('erispulse.adapter', [])
445
+ adapter_entries = entry_points.get('erispulse.adapter', []) # type: ignore[attr-defined] || 原因: 3.10.0后entry_points不再支持select方法
228
446
 
229
447
  # 处理适配器
448
+ logger.debug("正在处理适配器entry-points...")
230
449
  for entry_point in adapter_entries:
231
- adapter_objs, enabled_adapters, disabled_adapters = AdapterLoader._process_adapter(
450
+ adapter_objs, enabled_adapters, disabled_adapters = await AdapterLoader._process_adapter(
232
451
  entry_point, adapter_objs, enabled_adapters, disabled_adapters)
233
-
452
+
453
+ logger.info("适配器加载完成")
454
+
234
455
  except Exception as e:
235
456
  logger.error(f"加载适配器entry-points失败: {e}")
236
457
  raise ImportError(f"无法加载适配器: {e}")
237
-
458
+
238
459
  return adapter_objs, enabled_adapters, disabled_adapters
239
460
 
240
461
  @staticmethod
241
- def _process_adapter(
462
+ async def _process_adapter(
242
463
  entry_point: Any,
243
464
  adapter_objs: Dict[str, object],
244
465
  enabled_adapters: List[str],
@@ -261,12 +482,22 @@ class AdapterLoader:
261
482
  :raises ImportError: 当适配器加载失败时抛出
262
483
  """
263
484
  meta_name = entry_point.name
264
- adapter_status = module_registry.get_module_status(meta_name)
485
+
486
+ # # 检查适配器是否已经注册,如果未注册则进行注册(默认禁用)
487
+ # if not sdk.adapter.exists(meta_name):
488
+ # sdk.adapter._config_register(meta_name, False)
489
+ # logger.info(f"发现新适配器 {meta_name},默认已禁用,请在配置文件中配置适配器并决定是否启用")
490
+ if not sdk.adapter.exists(meta_name):
491
+ sdk.adapter._config_register(meta_name, True)
492
+ logger.info(f"发现新适配器 {meta_name},默认已启用")
493
+
494
+ # 获取适配器当前状态
495
+ adapter_status = sdk.adapter.is_enabled(meta_name)
265
496
  logger.debug(f"适配器 {meta_name} 状态: {adapter_status}")
266
497
 
267
- if adapter_status is False:
498
+ if not adapter_status:
268
499
  disabled_adapters.append(meta_name)
269
- logger.warning(f"适配器 {meta_name} 已禁用,跳过加载")
500
+ logger.debug(f"适配器 {meta_name} 已禁用, 跳过...")
270
501
  return adapter_objs, enabled_adapters, disabled_adapters
271
502
 
272
503
  try:
@@ -287,12 +518,9 @@ class AdapterLoader:
287
518
  }
288
519
 
289
520
  if not hasattr(adapter_obj, 'adapterInfo'):
290
- adapter_obj.adapterInfo = {}
521
+ setattr(adapter_obj, 'adapterInfo', {})
291
522
 
292
523
  adapter_obj.adapterInfo[meta_name] = adapter_info
293
-
294
- # 存储适配器信息
295
- module_registry.set_module(meta_name, adapter_info)
296
524
 
297
525
  adapter_objs[meta_name] = adapter_obj
298
526
  enabled_adapters.append(meta_name)
@@ -304,7 +532,6 @@ class AdapterLoader:
304
532
 
305
533
  return adapter_objs, enabled_adapters, disabled_adapters
306
534
 
307
-
308
535
  class ModuleLoader:
309
536
  """
310
537
  模块加载器
@@ -318,7 +545,7 @@ class ModuleLoader:
318
545
  """
319
546
 
320
547
  @staticmethod
321
- def load() -> Tuple[Dict[str, object], List[str], List[str]]:
548
+ async def load() -> Tuple[Dict[str, object], List[str], List[str]]:
322
549
  """
323
550
  从PyPI包entry-points加载模块
324
551
 
@@ -333,19 +560,23 @@ class ModuleLoader:
333
560
  enabled_modules = []
334
561
  disabled_modules = []
335
562
 
563
+ logger.info("正在加载模块entry-points...")
564
+
336
565
  try:
337
566
  # 加载模块entry-points
338
567
  entry_points = importlib.metadata.entry_points()
339
568
  if hasattr(entry_points, 'select'):
340
569
  module_entries = entry_points.select(group='erispulse.module')
341
570
  else:
342
- module_entries = entry_points.get('erispulse.module', [])
571
+ module_entries = entry_points.get('erispulse.module', []) # type: ignore[attr-defined] || 原因: 3.10.0后entry_points不再支持select方法
343
572
 
344
573
  # 处理模块
345
574
  for entry_point in module_entries:
346
- module_objs, enabled_modules, disabled_modules = ModuleLoader._process_module(
575
+ module_objs, enabled_modules, disabled_modules = await ModuleLoader._process_module(
347
576
  entry_point, module_objs, enabled_modules, disabled_modules)
348
-
577
+
578
+ logger.info("模块加载完成")
579
+
349
580
  except Exception as e:
350
581
  logger.error(f"加载模块entry-points失败: {e}")
351
582
  raise ImportError(f"无法加载模块: {e}")
@@ -353,7 +584,7 @@ class ModuleLoader:
353
584
  return module_objs, enabled_modules, disabled_modules
354
585
 
355
586
  @staticmethod
356
- def _process_module(
587
+ async def _process_module(
357
588
  entry_point: Any,
358
589
  module_objs: Dict[str, object],
359
590
  enabled_modules: List[str],
@@ -376,13 +607,23 @@ class ModuleLoader:
376
607
  :raises ImportError: 当模块加载失败时抛出
377
608
  """
378
609
  meta_name = entry_point.name
379
- module_status = module_registry.get_module_status(meta_name)
610
+
611
+ logger.debug(f"正在处理模块: {meta_name}")
612
+ # # 检查模块是否已经注册,如果未注册则进行注册(默认禁用)
613
+ # if not sdk.module.exists(meta_name):
614
+ # sdk.module._config_register(meta_name, False) # 默认禁用
615
+ # logger.info(f"发现新模块 {meta_name},默认已禁用,请在配置文件中手动启用")
616
+
617
+ if not sdk.module.exists(meta_name):
618
+ sdk.module._config_register(meta_name, True) # 默认启用
619
+ logger.info(f"发现新模块 {meta_name},默认已启用。如需禁用,请在配置文件中设置 ErisPulse.modules.status.{meta_name} = false")
620
+
621
+ # 获取模块当前状态
622
+ module_status = sdk.module.is_enabled(meta_name)
380
623
  logger.debug(f"模块 {meta_name} 状态: {module_status}")
381
624
 
382
- # 首先检查模块状态,如果明确为False则直接跳过
383
- if module_status is False:
625
+ if not module_status:
384
626
  disabled_modules.append(meta_name)
385
- logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
386
627
  return module_objs, enabled_modules, disabled_modules
387
628
 
388
629
  try:
@@ -390,6 +631,14 @@ class ModuleLoader:
390
631
  module_obj = sys.modules[loaded_obj.__module__]
391
632
  dist = importlib.metadata.distribution(entry_point.dist.name)
392
633
 
634
+ # 检查模块是否继承自 BaseModule
635
+ from .Core.Bases.module import BaseModule
636
+ is_base_module = inspect.isclass(loaded_obj) and issubclass(loaded_obj, BaseModule)
637
+
638
+ if not is_base_module:
639
+ logger.warning(f"模块 {meta_name} 未继承自 BaseModule,"\
640
+ "如果你是这个模块的作者,请检查 ErisPulse 的文档更新 并尽快迁移!")
641
+
393
642
  lazy_load = ModuleLoader._should_lazy_load(loaded_obj)
394
643
 
395
644
  module_info = {
@@ -400,16 +649,14 @@ class ModuleLoader:
400
649
  "author": getattr(module_obj, "__author__", ""),
401
650
  "license": getattr(module_obj, "__license__", ""),
402
651
  "package": entry_point.dist.name,
403
- "lazy_load": lazy_load
652
+ "lazy_load": lazy_load,
653
+ "is_base_module": is_base_module
404
654
  },
405
655
  "module_class": loaded_obj
406
656
  }
407
657
 
408
- module_obj.moduleInfo = module_info
658
+ setattr(module_obj, "moduleInfo", module_info)
409
659
 
410
- # 存储模块信息
411
- module_registry.set_module(meta_name, module_info)
412
-
413
660
  module_objs[meta_name] = module_obj
414
661
  enabled_modules.append(meta_name)
415
662
  logger.debug(f"从PyPI包加载模块: {meta_name}")
@@ -428,6 +675,22 @@ class ModuleLoader:
428
675
  :param module_class: Type 模块类
429
676
  :return: bool 如果返回 False,则立即加载;否则懒加载
430
677
  """
678
+
679
+ logger.debug(f"检查模块 {module_class.__name__} 是否应该懒加载")
680
+
681
+ # 首先检查全局懒加载配置
682
+ try:
683
+ from .Core._self_config import get_framework_config
684
+ framework_config = get_framework_config()
685
+ global_lazy_loading = framework_config.get("enable_lazy_loading", True)
686
+
687
+ # 如果全局禁用懒加载,则直接返回False
688
+ if not global_lazy_loading:
689
+ logger.debug(f"全局懒加载已禁用,模块 {module_class.__name__} 将立即加载")
690
+ return False
691
+ except Exception as e:
692
+ logger.warning(f"获取框架配置失败: {e},将使用模块默认配置")
693
+
431
694
  # 检查模块是否定义了 should_eager_load() 方法
432
695
  if hasattr(module_class, "should_eager_load"):
433
696
  try:
@@ -441,7 +704,7 @@ class ModuleLoader:
441
704
 
442
705
  class ModuleInitializer:
443
706
  """
444
- 模块初始化器
707
+ 模块初始化器(注意:适配器是一个特殊的模块)
445
708
 
446
709
  负责协调适配器和模块的初始化流程
447
710
 
@@ -452,10 +715,10 @@ class ModuleInitializer:
452
715
  """
453
716
 
454
717
  @staticmethod
455
- def init() -> bool:
718
+ async def init() -> bool:
456
719
  """
457
720
  初始化所有模块和适配器
458
-
721
+
459
722
  执行步骤:
460
723
  1. 从PyPI包加载适配器
461
724
  2. 从PyPI包加载模块
@@ -469,14 +732,36 @@ class ModuleInitializer:
469
732
  logger.info("[Init] SDK 正在初始化...")
470
733
 
471
734
  try:
472
- # 1. 先加载适配器
473
- adapter_objs, enabled_adapters, disabled_adapters = AdapterLoader.load()
474
- logger.info(f"[Init] 加载了 {len(enabled_adapters)} 个适配器, {len(disabled_adapters)} 个适配器被禁用")
735
+ # 1. 并行加载适配器和模块
736
+ (adapter_result, module_result) = await asyncio.gather(
737
+ AdapterLoader.load(),
738
+ ModuleLoader.load(),
739
+ return_exceptions=True
740
+ )
475
741
 
476
- # 2. 再加载模块
477
- module_objs, enabled_modules, disabled_modules = ModuleLoader.load()
478
- logger.info(f"[Init] 加载了 {len(enabled_modules)} 个模块, {len(disabled_modules)} 个模块被禁用")
742
+ # 检查是否有异常
743
+ if isinstance(adapter_result, Exception):
744
+ logger.error(f"[Init] 适配器加载失败: {adapter_result}")
745
+ return False
746
+
747
+ if isinstance(module_result, Exception):
748
+ logger.error(f"[Init] 模块加载失败: {module_result}")
749
+ return False
479
750
 
751
+ # 解包结果
752
+ if not isinstance(adapter_result, Exception):
753
+ adapter_objs, enabled_adapters, disabled_adapters = adapter_result # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查
754
+ else:
755
+ return False
756
+
757
+ if not isinstance(module_result, Exception):
758
+ module_objs, enabled_modules, disabled_modules = module_result # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查
759
+ else:
760
+ return False
761
+
762
+ logger.info(f"[Init] 加载了 {len(enabled_adapters)} 个适配器, {len(disabled_adapters)} 个适配器被禁用")
763
+ logger.info(f"[Init] 加载了 {len(enabled_modules)} 个模块, {len(disabled_modules)} 个模块被禁用")
764
+
480
765
  modules_dir = os.path.join(os.path.dirname(__file__), "modules")
481
766
  if os.path.exists(modules_dir) and os.listdir(modules_dir):
482
767
  logger.warning("[Warning] 你的项目使用了已经弃用的模块加载方式, 请尽快使用 PyPI 模块加载方式代替")
@@ -487,21 +772,43 @@ class ModuleInitializer:
487
772
 
488
773
  # 3. 注册适配器
489
774
  logger.debug("[Init] 正在注册适配器...")
490
- if not ModuleInitializer._register_adapters(enabled_adapters, adapter_objs):
775
+ if not await ModuleInitializer._register_adapters(enabled_adapters, adapter_objs):
491
776
  return False
492
-
777
+
493
778
  # 4. 初始化模块
494
779
  logger.debug("[Init] 正在初始化模块...")
495
- success = ModuleInitializer._initialize_modules(enabled_modules, module_objs)
496
- logger.info(f"[Init] SDK初始化{'成功' if success else '失败'}")
780
+ success = await ModuleInitializer._initialize_modules(enabled_modules, module_objs)
781
+
782
+ if success:
783
+ logger.info("[Init] SDK初始化成功")
784
+ else:
785
+ logger.error("[Init] SDK初始化失败")
786
+
787
+ load_duration = lifecycle.stop_timer("core.init")
788
+ await lifecycle.submit_event(
789
+ "core.init.complete",
790
+ msg="模块初始化完成" if success else "模块初始化失败",
791
+ data={
792
+ "duration": load_duration,
793
+ "success": success
794
+ }
795
+ )
497
796
  return success
498
797
 
499
798
  except Exception as e:
799
+ load_duration = lifecycle.stop_timer("core.init")
800
+ await lifecycle.submit_event(
801
+ "core.init.complete",
802
+ msg="模块初始化失败",
803
+ data={
804
+ "duration": load_duration,
805
+ "success": False
806
+ }
807
+ )
500
808
  logger.critical(f"SDK初始化严重错误: {e}")
501
809
  return False
502
-
503
810
  @staticmethod
504
- def _initialize_modules(modules: List[str], module_objs: Dict[str, Any]) -> bool:
811
+ async def _initialize_modules(modules: List[str], module_objs: Dict[str, Any]) -> bool:
505
812
  """
506
813
  {!--< internal-use >!--}
507
814
  初始化模块
@@ -511,73 +818,112 @@ class ModuleInitializer:
511
818
 
512
819
  :return: bool 模块初始化是否成功
513
820
  """
514
- # 将所有模块挂载到LazyModule代理上
821
+ # 并行注册所有模块类
822
+ register_tasks = []
515
823
  for module_name in modules:
516
824
  module_obj = module_objs[module_name]
517
825
  meta_name = module_obj.moduleInfo["meta"]["name"]
518
826
 
519
- if hasattr(sdk, meta_name):
520
- continue
521
-
522
- try:
523
- entry_points = importlib.metadata.entry_points()
524
- if hasattr(entry_points, 'select'):
525
- module_entries = entry_points.select(group='erispulse.module')
526
- module_entry_map = {entry.name: entry for entry in module_entries}
527
- else:
528
- module_entries = entry_points.get('erispulse.module', [])
529
- module_entry_map = {entry.name: entry for entry in module_entries}
530
-
531
- entry_point = module_entry_map.get(meta_name)
532
- if entry_point:
533
- module_class = entry_point.load()
827
+ async def register_module(name, obj):
828
+ try:
829
+ entry_points = importlib.metadata.entry_points()
830
+ if hasattr(entry_points, 'select'):
831
+ module_entries = entry_points.select(group='erispulse.module')
832
+ module_entry_map = {entry.name: entry for entry in module_entries}
833
+ else:
834
+ module_entries = entry_points.get('erispulse.module', []) # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查,这是一个兼容性的写法
835
+ module_entry_map = {entry.name: entry for entry in module_entries}
534
836
 
535
- # 创建LazyModule代理
536
- lazy_module = LazyModule(meta_name, module_class, sdk, module_obj.moduleInfo)
537
- setattr(sdk, meta_name, lazy_module)
538
-
539
- logger.debug(f"预注册模块: {meta_name}")
540
-
541
- except Exception as e:
542
- logger.error(f"预注册模块 {meta_name} 失败: {e}")
543
- setattr(sdk, meta_name, None)
544
- return False
837
+ entry_point = module_entry_map.get(name)
838
+ if entry_point:
839
+ module_class = entry_point.load()
840
+
841
+ module.register(name, module_class, obj.moduleInfo)
842
+ logger.debug(f"注册模块类: {name}")
843
+ return True
844
+ return False
845
+ except Exception as e:
846
+ logger.error(f"注册模块 {name} 失败: {e}")
847
+ return False
848
+
849
+ register_tasks.append(register_module(meta_name, module_obj))
850
+
851
+ # 等待所有注册任务完成
852
+ register_results = await asyncio.gather(*register_tasks, return_exceptions=True)
853
+
854
+ # 检查是否有注册失败的情况
855
+ if any(isinstance(result, Exception) or result is False for result in register_results):
856
+ return False
545
857
 
546
- # 检查并初始化需要立即加载的模块
858
+ # 将所有模块挂载到sdk对象上
547
859
  for module_name in modules:
548
860
  module_obj = module_objs[module_name]
549
861
  meta_name = module_obj.moduleInfo["meta"]["name"]
862
+ lazy_load = module_obj.moduleInfo["meta"].get("lazy_load", True)
550
863
 
551
- if not hasattr(sdk, meta_name):
552
- continue
553
-
554
- try:
555
- entry_points = importlib.metadata.entry_points()
556
- if hasattr(entry_points, 'select'):
557
- module_entries = entry_points.select(group='erispulse.module')
558
- module_entry_map = {entry.name: entry for entry in module_entries}
559
- else:
560
- module_entries = entry_points.get('erispulse.module', [])
561
- module_entry_map = {entry.name: entry for entry in module_entries}
562
-
563
- entry_point = module_entry_map.get(meta_name)
564
- if entry_point:
565
- module_class = entry_point.load()
566
-
864
+ if lazy_load:
865
+ # 使用懒加载方式挂载
866
+ lazy_module = LazyModule(
867
+ meta_name,
868
+ module_obj.moduleInfo["module_class"],
869
+ sdk,
870
+ module_obj.moduleInfo
871
+ )
872
+ setattr(sdk, meta_name, lazy_module)
873
+ logger.debug(f"挂载懒加载模块到sdk: {meta_name}")
874
+ else:
875
+ # 立即加载的模块暂时挂载为None,稍后会加载
876
+ setattr(sdk, meta_name, None)
877
+ logger.debug(f"预挂载立即加载模块到sdk: {meta_name}")
878
+
879
+ # 并行初始化需要立即加载的模块
880
+ eager_load_tasks = []
881
+ for module_name in modules:
882
+ module_obj = module_objs[module_name]
883
+ meta_name = module_obj.moduleInfo["meta"]["name"]
884
+
885
+ async def load_module_if_eager(name, obj):
886
+ try:
567
887
  # 检查是否需要立即加载
568
- lazy_load = ModuleLoader._should_lazy_load(module_class)
569
- if not lazy_load:
570
- # 触发LazyModule的初始化
571
- getattr(sdk, meta_name)._initialize()
572
- logger.debug(f"立即初始化模块: {meta_name}")
888
+ entry_points = importlib.metadata.entry_points()
889
+ if hasattr(entry_points, 'select'):
890
+ module_entries = entry_points.select(group='erispulse.module')
891
+ module_entry_map = {entry.name: entry for entry in module_entries}
892
+ else:
893
+ module_entries = entry_points.get('erispulse.module', []) # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查,这是一个兼容性的写法
894
+ module_entry_map = {entry.name: entry for entry in module_entries}
895
+
896
+ entry_point = module_entry_map.get(name)
897
+ if entry_point:
898
+ module_class = entry_point.load()
573
899
 
574
- except Exception as e:
575
- logger.error(f"初始化模块 {meta_name} 失败: {e}")
576
- return False
577
-
578
- return True
900
+ # 检查是否需要立即加载
901
+ lazy_load = ModuleLoader._should_lazy_load(module_class)
902
+ if not lazy_load:
903
+ # 立即加载模块
904
+ result = await module.load(name)
905
+ if not result:
906
+ logger.error(f"加载模块 {name} 失败")
907
+ else:
908
+ logger.debug(f"立即加载模块: {name}")
909
+ # 更新sdk上的引用
910
+ setattr(sdk, name, module.get(name))
911
+ return result
912
+ return True # 不需要立即加载的模块返回True
913
+ except Exception as e:
914
+ logger.error(f"初始化模块 {name} 失败: {e}")
915
+ return False
916
+
917
+ eager_load_tasks.append(load_module_if_eager(meta_name, module_obj))
918
+
919
+ # 等待所有立即加载任务完成
920
+ load_results = await asyncio.gather(*eager_load_tasks, return_exceptions=True)
921
+
922
+ # 检查是否有加载失败的情况
923
+ return not any(isinstance(result, Exception) or result is False for result in load_results)
924
+
579
925
  @staticmethod
580
- def _register_adapters(adapters: List[str], adapter_objs: Dict[str, Any]) -> bool:
926
+ async def _register_adapters(adapters: List[str], adapter_objs: Dict[str, Any]) -> bool:
581
927
  """
582
928
  {!--< internal-use >!--}
583
929
  注册适配器
@@ -587,46 +933,57 @@ class ModuleInitializer:
587
933
 
588
934
  :return: bool 适配器注册是否成功
589
935
  """
590
- success = True
591
- registered_classes = {}
592
-
936
+ # 并行注册所有适配器
937
+ register_tasks = []
938
+
593
939
  for adapter_name in adapters:
594
940
  adapter_obj = adapter_objs[adapter_name]
595
941
 
596
- try:
597
- if hasattr(adapter_obj, "adapterInfo") and isinstance(adapter_obj.adapterInfo, dict):
598
- for platform, adapter_info in adapter_obj.adapterInfo.items():
599
- if platform in sdk.adapter._adapters:
600
- continue
601
-
602
- adapter_class = adapter_info["adapter_class"]
603
-
604
- if adapter_class in registered_classes:
605
- instance = registered_classes[adapter_class]
606
- # 改为直接操作适配器字典而不是调用register
607
- sdk.adapter._adapters[platform] = instance
608
- sdk.adapter._platform_to_instance[platform] = instance
609
- logger.debug(f"复用适配器实例 {adapter_class.__name__} 到平台别称 {platform}")
610
- else:
611
- init_signature = inspect.signature(adapter_class.__init__)
612
- params = init_signature.parameters
613
-
614
- if 'sdk' in params:
615
- instance = adapter_class(sdk)
616
- else:
617
- instance = adapter_class()
942
+ async def register_single_adapter(name, obj):
943
+ try:
944
+ success = True
945
+ if hasattr(obj, "adapterInfo") and isinstance(obj.adapterInfo, dict):
946
+ for platform, adapter_info in obj.adapterInfo.items():
947
+ if platform in adapter._adapters:
948
+ continue
949
+
950
+ adapter_class = adapter_info["adapter_class"]
618
951
 
619
- # 直接操作适配器字典
620
- sdk.adapter._adapters[platform] = instance
621
- sdk.adapter._platform_to_instance[platform] = instance
622
- registered_classes[adapter_class] = instance
952
+ adapter.register(platform, adapter_class, adapter_info)
623
953
  logger.info(f"注册适配器: {platform} ({adapter_class.__name__})")
624
- except Exception as e:
625
- logger.error(f"适配器 {adapter_name} 注册失败: {e}")
626
- success = False
627
- return success
628
-
629
- def init_progress() -> bool:
954
+
955
+ # 提交适配器加载完成事件
956
+ await lifecycle.submit_event(
957
+ "adapter.load",
958
+ msg=f"适配器 {platform} 加载完成",
959
+ data={
960
+ "platform": platform,
961
+ "success": True
962
+ }
963
+ )
964
+ return success
965
+ except Exception as e:
966
+ logger.error(f"适配器 {name} 注册失败: {e}")
967
+ # 提交适配器加载失败事件
968
+ await lifecycle.submit_event(
969
+ "adapter.load",
970
+ msg=f"适配器 {name} 加载失败: {e}",
971
+ data={
972
+ "platform": name,
973
+ "success": False
974
+ }
975
+ )
976
+ return False
977
+
978
+ register_tasks.append(register_single_adapter(adapter_name, adapter_obj))
979
+
980
+ # 等待所有注册任务完成
981
+ register_results = await asyncio.gather(*register_tasks, return_exceptions=True)
982
+
983
+ # 检查是否有注册失败的情况
984
+ return not any(isinstance(result, Exception) or result is False for result in register_results)
985
+
986
+ async def init_progress() -> bool:
630
987
  """
631
988
  初始化项目环境文件
632
989
 
@@ -653,7 +1010,7 @@ from ErisPulse import sdk
653
1010
 
654
1011
  async def main():
655
1012
  try:
656
- isInit = await sdk.init_task()
1013
+ isInit = await sdk.init()
657
1014
 
658
1015
  if not isInit:
659
1016
  sdk.logger.error("ErisPulse 初始化失败,请检查日志")
@@ -679,11 +1036,10 @@ if __name__ == "__main__":
679
1036
 
680
1037
  return main_init
681
1038
  except Exception as e:
682
- sdk.logger.error(f"无法初始化项目环境: {e}")
1039
+ logger.error(f"无法初始化项目环境: {e}")
683
1040
  return False
684
1041
 
685
-
686
- def _prepare_environment() -> bool:
1042
+ async def _prepare_environment() -> bool:
687
1043
  """
688
1044
  {!--< internal-use >!--}
689
1045
  准备运行环境
@@ -692,29 +1048,45 @@ def _prepare_environment() -> bool:
692
1048
 
693
1049
  :return: bool 环境准备是否成功
694
1050
  """
1051
+ await lifecycle.submit_event(
1052
+ "core.init.start",
1053
+ msg="开始初始化"
1054
+ )
1055
+ lifecycle.start_timer("core.init")
1056
+
695
1057
  logger.info("[Init] 准备初始化环境...")
696
1058
  try:
697
- from .Core.erispulse_config import get_erispulse_config
1059
+ from .Core._self_config import get_erispulse_config
698
1060
  get_erispulse_config()
699
1061
  logger.info("[Init] 配置文件已加载")
700
-
701
- main_init = init_progress()
1062
+
1063
+ main_init = await init_progress()
702
1064
  if main_init:
703
1065
  logger.info("[Init] 项目入口已生成, 你可以在 main.py 中编写一些代码")
704
1066
  return True
705
1067
  except Exception as e:
1068
+ load_duration = lifecycle.stop_timer("core.init")
1069
+ await lifecycle.submit_event(
1070
+ "core.init.complete",
1071
+ msg="模块初始化失败",
1072
+ data={
1073
+ "duration": load_duration,
1074
+ "success": False
1075
+ }
1076
+ )
706
1077
  logger.error(f"环境准备失败: {e}")
707
1078
  return False
708
1079
 
709
- def init() -> bool:
1080
+ async def init() -> bool:
710
1081
  """
711
1082
  SDK初始化入口
712
1083
 
713
1084
  :return: bool SDK初始化是否成功
714
1085
  """
715
- if not _prepare_environment():
1086
+ if not await _prepare_environment():
716
1087
  return False
717
- return ModuleInitializer.init()
1088
+
1089
+ return await ModuleInitializer.init()
718
1090
 
719
1091
  def init_task() -> asyncio.Task:
720
1092
  """
@@ -723,9 +1095,9 @@ def init_task() -> asyncio.Task:
723
1095
  :return: asyncio.Task 初始化任务
724
1096
  """
725
1097
  async def _async_init():
726
- if not _prepare_environment():
1098
+ if not await _prepare_environment():
727
1099
  return False
728
- return ModuleInitializer.init()
1100
+ return await ModuleInitializer.init()
729
1101
 
730
1102
  try:
731
1103
  return asyncio.create_task(_async_init())
@@ -733,8 +1105,96 @@ def init_task() -> asyncio.Task:
733
1105
  loop = asyncio.new_event_loop()
734
1106
  asyncio.set_event_loop(loop)
735
1107
  return loop.create_task(_async_init())
1108
+ async def uninit() -> bool:
1109
+ """
1110
+ SDK反初始化
1111
+
1112
+ 执行以下操作:
1113
+ 1. 关闭所有适配器
1114
+ 2. 卸载所有模块
1115
+ 3. 清理所有事件处理器
1116
+ 4. 清理僵尸线程
1117
+
1118
+ :return: bool 反初始化是否成功
1119
+ """
1120
+ try:
1121
+ logger.info("[Uninit] 开始反初始化SDK...")
1122
+
1123
+ # 1. 关闭所有适配器
1124
+ logger.debug("[Uninit] 正在关闭适配器...")
1125
+ await adapter.shutdown()
1126
+
1127
+ # 2. 卸载所有模块
1128
+ logger.debug("[Uninit] 正在卸载模块...")
1129
+ await module.unload()
1130
+
1131
+ # 3. 清理Event模块中的所有事件处理器
1132
+ Event._clear_all_handlers()
1133
+
1134
+ # 4. 清理僵尸线程
1135
+ logger.debug("[Uninit] 正在清理线程...")
1136
+ # SDK本身不创建线程,但可以记录可能的线程泄漏
1137
+ current_task = asyncio.current_task()
1138
+ logger.debug(f"[Uninit] 当前任务: {current_task}")
1139
+
1140
+ logger.info("[Uninit] SDK反初始化完成")
1141
+ return True
1142
+
1143
+ except Exception as e:
1144
+ logger.error(f"[Uninit] SDK反初始化失败: {e}")
1145
+ return False
1146
+
1147
+ async def restart() -> bool:
1148
+ """
1149
+ SDK重新启动
1150
+
1151
+ 执行完整的反初始化后再初始化过程
1152
+
1153
+ :return: bool 重新加载是否成功
1154
+ """
1155
+ logger.info("[Reload] 开始重新加载SDK...")
1156
+
1157
+ # 先执行反初始化
1158
+ if not await uninit():
1159
+ logger.error("[Reload] 反初始化失败,无法继续重新加载")
1160
+ return False
1161
+
1162
+ # 再执行初始化
1163
+ logger.info("[Reload] 开始重新初始化SDK...")
1164
+ if not await init():
1165
+ logger.error("[Reload] 初始化失败,请检查日志")
1166
+ return False
1167
+
1168
+ logger.info("[Reload] 正在启动适配器...")
1169
+ await adapter.startup()
1170
+
1171
+ logger.info("[Reload] 重新加载完成")
1172
+ return True
736
1173
 
737
- def load_module(module_name: str) -> bool:
1174
+ async def run() -> None:
1175
+ """
1176
+ 无头模式运行ErisPulse
1177
+
1178
+ 此方法提供了一种无需入口启动的方式,适用于与其它框架集成的场景
1179
+ """
1180
+ try:
1181
+ isInit = await init()
1182
+
1183
+ if not isInit:
1184
+ logger.error("ErisPulse 初始化失败,请检查日志")
1185
+ return
1186
+
1187
+ await adapter.startup()
1188
+
1189
+ # 保持程序运行
1190
+ await asyncio.Event().wait()
1191
+ except Exception as e:
1192
+ logger.error(e)
1193
+ finally:
1194
+ await module.unload()
1195
+ await adapter.shutdown()
1196
+
1197
+ async def load_module(module_name: str) -> bool:
738
1198
  """
739
1199
  手动加载指定模块
740
1200
 
@@ -744,15 +1204,29 @@ def load_module(module_name: str) -> bool:
744
1204
  {!--< tips >!--}
745
1205
  1. 可用于手动触发懒加载模块的初始化
746
1206
  2. 如果模块不存在或已加载会返回False
1207
+ 3. 对于需要异步初始化的模块,这是唯一的加载方式
747
1208
  {!--< /tips >!--}
748
1209
  """
749
1210
  try:
750
- module = getattr(sdk, module_name, None)
751
- if isinstance(module, LazyModule):
752
- # 触发懒加载模块的初始化
753
- module._initialize()
754
- return True
755
- elif module is not None:
1211
+ module_instance = getattr(sdk, module_name, None)
1212
+ if isinstance(module_instance, LazyModule):
1213
+ # 检查模块是否需要异步初始化
1214
+ if hasattr(module_instance, '_needs_async_init') and object.__getattribute__(module_instance, '_needs_async_init'):
1215
+ # 对于需要异步初始化的模块,执行完整异步初始化
1216
+ await module_instance._initialize()
1217
+ object.__setattr__(module_instance, '_needs_async_init', False) # 清除标志
1218
+ return True
1219
+ # 检查模块是否已经同步初始化但未完成异步部分
1220
+ elif (object.__getattribute__(module_instance, '_initialized') and
1221
+ object.__getattribute__(module_instance, '_is_base_module')):
1222
+ # 如果是BaseModule子类且已同步初始化,只需完成异步部分
1223
+ await module_instance._complete_async_init()
1224
+ return True
1225
+ else:
1226
+ # 触发懒加载模块的完整初始化
1227
+ await module_instance._initialize()
1228
+ return True
1229
+ elif module_instance is not None:
756
1230
  logger.warning(f"模块 {module_name} 已经加载")
757
1231
  return False
758
1232
  else:
@@ -761,7 +1235,11 @@ def load_module(module_name: str) -> bool:
761
1235
  except Exception as e:
762
1236
  logger.error(f"加载模块 {module_name} 失败: {e}")
763
1237
  return False
764
-
765
-
766
- sdk.init = init
767
- sdk.load_module = load_module
1238
+
1239
+ logger.debug("ErisPulse 正在挂载必要的入口方法")
1240
+ setattr(sdk, "init", init)
1241
+ setattr(sdk, "init_task", init_task)
1242
+ setattr(sdk, "load_module", load_module)
1243
+ setattr(sdk, "run", run)
1244
+ setattr(sdk, "restart", restart)
1245
+ setattr(sdk, "uninit", uninit)