ErisPulse 2.4.6.dev3__tar.gz → 2.4.6.dev4__tar.gz
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-2.4.6.dev3 → erispulse-2.4.6.dev4}/PKG-INFO +1 -1
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/pyproject.toml +1 -1
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/run.py +31 -9
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/run.pyi +3 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/adapter.py +26 -18
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/module.py +12 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/adapter.py +16 -2
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/module.py +35 -1
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/sdk.py +34 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/sdk.pyi +19 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/.gitignore +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/LICENSE +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/README.md +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/base.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/base.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/cli.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/cli.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/create.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/create.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/init.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/init.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/install.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/install.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/list.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/list.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/list_remote.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/self_update.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/self_update.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/uninstall.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/commands/upgrade.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/console.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/console.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/registry.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/registry.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/utils/display.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/utils/display.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/CLI/utils/package_manager.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/adapter.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/adapter.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/manager.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/manager.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/module.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/module.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/storage.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Bases/storage.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/base.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/base.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/command.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/command.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/message.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/message.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/message_builder.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/message_builder.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/meta.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/meta.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/notice.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/notice.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/request.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/request.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/session_type.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/session_type.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/wrapper.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/Event/wrapper.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/adapter.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/config.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/config.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/constants.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/constants.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/lifecycle.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/lifecycle.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/logger.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/logger.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/module.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/router.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/router.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/storage.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/Core/storage.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/__main__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/adapter.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/bases/finder.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/bases/finder.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/finders/module.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/adapter.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/bases/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/bases/loader.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/bases/loader.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/module.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/strategy.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/loaders/strategy.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/context.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/context.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/exceptions.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/exceptions.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/frame_config.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/runtime/frame_config.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/web_status/4xx.png +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/web_status/5xx.png +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/web_status/__init__.py +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/web_status/__init__.pyi +0 -0
- {erispulse-2.4.6.dev3 → erispulse-2.4.6.dev4}/src/ErisPulse/web_status/unknow.png +0 -0
|
@@ -116,28 +116,50 @@ class RunCommand(Command):
|
|
|
116
116
|
else:
|
|
117
117
|
self._run_internal(reload_mode)
|
|
118
118
|
|
|
119
|
+
_RESTART_EXIT_CODE = 42
|
|
120
|
+
|
|
119
121
|
def _run_internal(self, reload_mode: bool):
|
|
120
122
|
"""
|
|
121
123
|
直接运行 SDK(不指定脚本时)
|
|
124
|
+
|
|
125
|
+
以子进程方式运行 SDK,支持硬重启:当 SDK 进程以特定退出码退出时,
|
|
126
|
+
自动重新启动新进程,确保资源完全释放。
|
|
122
127
|
"""
|
|
123
128
|
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
if reload_mode:
|
|
130
|
+
async def _run():
|
|
131
|
+
from ... import sdk
|
|
126
132
|
|
|
127
|
-
if reload_mode:
|
|
128
133
|
loop = asyncio.get_running_loop()
|
|
129
134
|
self._setup_watchdog(".", loop)
|
|
135
|
+
await sdk.run(keep_running=True)
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
try:
|
|
138
|
+
asyncio.run(_run())
|
|
139
|
+
except KeyboardInterrupt:
|
|
140
|
+
pass
|
|
141
|
+
finally:
|
|
142
|
+
if hasattr(self, "_observer"):
|
|
143
|
+
self._observer.stop()
|
|
144
|
+
self._observer.join()
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
cmd = [sys.executable, "-c",
|
|
148
|
+
"import asyncio; from ErisPulse import sdk; "
|
|
149
|
+
"asyncio.run(sdk.run(keep_running=True))"]
|
|
132
150
|
|
|
133
151
|
try:
|
|
134
|
-
|
|
152
|
+
while True:
|
|
153
|
+
process = subprocess.Popen(cmd)
|
|
154
|
+
process.wait()
|
|
155
|
+
|
|
156
|
+
if process.returncode == self._RESTART_EXIT_CODE:
|
|
157
|
+
console.print("[info]收到硬重启请求,正在重新启动...[/]")
|
|
158
|
+
time.sleep(0.5)
|
|
159
|
+
continue
|
|
160
|
+
break
|
|
135
161
|
except KeyboardInterrupt:
|
|
136
162
|
pass
|
|
137
|
-
finally:
|
|
138
|
-
if reload_mode and hasattr(self, "_observer"):
|
|
139
|
-
self._observer.stop()
|
|
140
|
-
self._observer.join()
|
|
141
163
|
|
|
142
164
|
def _run_script(self, script_path: str, reload_mode: bool):
|
|
143
165
|
script_path_abs = os.path.abspath(script_path)
|
|
@@ -53,6 +53,9 @@ class RunCommand(Command):
|
|
|
53
53
|
def _run_internal(self: object, reload_mode: bool) -> ...:
|
|
54
54
|
"""
|
|
55
55
|
直接运行 SDK(不指定脚本时)
|
|
56
|
+
|
|
57
|
+
以子进程方式运行 SDK,支持硬重启:当 SDK 进程以特定退出码退出时,
|
|
58
|
+
自动重新启动新进程,确保资源完全释放。
|
|
56
59
|
"""
|
|
57
60
|
...
|
|
58
61
|
def _run_script(self: object, script_path: str, reload_mode: bool) -> ...:
|
|
@@ -135,24 +135,32 @@ class AdapterManager(ManagerBase):
|
|
|
135
135
|
if existing_instance is not None:
|
|
136
136
|
self._adapters[platform] = existing_instance
|
|
137
137
|
else:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
138
|
+
try:
|
|
139
|
+
# 创建适配器实例
|
|
140
|
+
# 检查适配器类 __init__ 方法的参数
|
|
141
|
+
init_signature = inspect.signature(adapter_class.__init__)
|
|
142
|
+
params = [p for p in init_signature.parameters.values() if p.name != "self"]
|
|
143
|
+
|
|
144
|
+
sdk_to_use = self._sdk
|
|
145
|
+
if sdk_to_use is None:
|
|
146
|
+
from .. import sdk
|
|
147
|
+
|
|
148
|
+
sdk_to_use = sdk
|
|
149
|
+
|
|
150
|
+
# 根据参数情况创建实例
|
|
151
|
+
if params:
|
|
152
|
+
instance = adapter_class(sdk_to_use)
|
|
153
|
+
else:
|
|
154
|
+
instance = adapter_class()
|
|
155
|
+
|
|
156
|
+
self._adapters[platform] = instance
|
|
157
|
+
except SystemExit as e:
|
|
158
|
+
logger.error(f"适配器 {platform} 尝试退出进程 (SystemExit({e.code})),已跳过。"
|
|
159
|
+
f"请不要在适配器中使用 sys.exit() 或 raise SystemExit")
|
|
160
|
+
return False
|
|
161
|
+
except Exception as e:
|
|
162
|
+
logger.error(f"创建适配器实例 {platform} 失败: {e}")
|
|
163
|
+
return False
|
|
156
164
|
|
|
157
165
|
return True
|
|
158
166
|
|
|
@@ -203,6 +203,18 @@ class ModuleManager(ManagerBase):
|
|
|
203
203
|
logger.info(f"模块 {module_name} 加载成功")
|
|
204
204
|
return True
|
|
205
205
|
|
|
206
|
+
except SystemExit as e:
|
|
207
|
+
await lifecycle.submit_event(
|
|
208
|
+
"module.load",
|
|
209
|
+
data={
|
|
210
|
+
"module_name": module_name,
|
|
211
|
+
"success": False,
|
|
212
|
+
},
|
|
213
|
+
msg=f"模块 {module_name} 尝试退出进程 (SystemExit)",
|
|
214
|
+
)
|
|
215
|
+
logger.error(f"模块 {module_name} 尝试退出进程 (SystemExit({e.code})),已跳过该模块。"
|
|
216
|
+
f"请不要在模块中使用 sys.exit() 或 raise SystemExit,请改用 raise RuntimeError 或返回错误")
|
|
217
|
+
return False
|
|
206
218
|
except Exception as e:
|
|
207
219
|
await lifecycle.submit_event(
|
|
208
220
|
"module.load",
|
|
@@ -91,8 +91,10 @@ class AdapterLoader(BaseLoader):
|
|
|
91
91
|
|
|
92
92
|
logger.print_section_separator()
|
|
93
93
|
|
|
94
|
-
except
|
|
94
|
+
except BaseException as e:
|
|
95
95
|
logger.error(f"加载 {group_name} entry-points 失败: {e}")
|
|
96
|
+
if isinstance(e, SystemExit):
|
|
97
|
+
logger.warning(f"拦截到 SystemExit,已阻止进程退出,跳过后续适配器加载")
|
|
96
98
|
|
|
97
99
|
return objs, enabled_list, disabled_list
|
|
98
100
|
|
|
@@ -172,6 +174,9 @@ class AdapterLoader(BaseLoader):
|
|
|
172
174
|
objs[meta_name] = adapter_obj
|
|
173
175
|
enabled_list.append(meta_name)
|
|
174
176
|
|
|
177
|
+
except SystemExit as e:
|
|
178
|
+
logger.error(f"加载适配器 {meta_name} 时触发 SystemExit({e.code}),已跳过。"
|
|
179
|
+
f"请不要在适配器中使用 sys.exit() 或 raise SystemExit")
|
|
175
180
|
except Exception as e:
|
|
176
181
|
logger.error(f"加载适配器 {meta_name} 失败,已跳过: {e}")
|
|
177
182
|
|
|
@@ -224,6 +229,15 @@ class AdapterLoader(BaseLoader):
|
|
|
224
229
|
data={"platform": platform, "success": True},
|
|
225
230
|
)
|
|
226
231
|
return success
|
|
232
|
+
except SystemExit as e:
|
|
233
|
+
logger.error(f"适配器 {name} 注册时尝试退出进程 (SystemExit({e.code})),已跳过。"
|
|
234
|
+
f"请不要使用 sys.exit() 或 raise SystemExit")
|
|
235
|
+
await lifecycle.submit_event(
|
|
236
|
+
"adapter.load",
|
|
237
|
+
msg=f"适配器 {name} 注册时触发 SystemExit",
|
|
238
|
+
data={"platform": name, "success": False},
|
|
239
|
+
)
|
|
240
|
+
return False
|
|
227
241
|
except Exception as e:
|
|
228
242
|
logger.error(f"适配器 {name} 注册失败: {e}")
|
|
229
243
|
# 提交适配器加载失败事件
|
|
@@ -243,7 +257,7 @@ class AdapterLoader(BaseLoader):
|
|
|
243
257
|
failed_adapters = []
|
|
244
258
|
for i, result in enumerate(register_results):
|
|
245
259
|
adapter_name = adapters[i]
|
|
246
|
-
if isinstance(result,
|
|
260
|
+
if isinstance(result, BaseException) or result is False:
|
|
247
261
|
logger.warning(f"适配器 {adapter_name} 注册失败,已跳过")
|
|
248
262
|
failed_adapters.append(adapter_name)
|
|
249
263
|
|
|
@@ -93,6 +93,9 @@ class ModuleLoader(BaseLoader):
|
|
|
93
93
|
|
|
94
94
|
logger.print_section_separator()
|
|
95
95
|
|
|
96
|
+
except SystemExit as e:
|
|
97
|
+
logger.error(f"加载 {group_name} 时触发 SystemExit({e.code}),已阻止进程退出。"
|
|
98
|
+
f"请不要使用 sys.exit() 或 raise SystemExit")
|
|
96
99
|
except Exception as e:
|
|
97
100
|
logger.error(f"加载 {group_name} entry-points 失败: {e}")
|
|
98
101
|
|
|
@@ -191,6 +194,9 @@ class ModuleLoader(BaseLoader):
|
|
|
191
194
|
objs[meta_name] = module_obj
|
|
192
195
|
enabled_list.append(meta_name)
|
|
193
196
|
|
|
197
|
+
except SystemExit as e:
|
|
198
|
+
logger.error(f"加载模块 {meta_name} 时尝试退出进程 (SystemExit({e.code})),已跳过。"
|
|
199
|
+
f"请不要使用 sys.exit() 或 raise SystemExit")
|
|
194
200
|
except Exception as e:
|
|
195
201
|
logger.error(f"从 entry-point 加载模块 {meta_name} 失败,已跳过: {e}")
|
|
196
202
|
|
|
@@ -355,6 +361,10 @@ class ModuleLoader(BaseLoader):
|
|
|
355
361
|
manager_instance.register(name, module_class, obj.moduleInfo)
|
|
356
362
|
return True
|
|
357
363
|
return False
|
|
364
|
+
except SystemExit as e:
|
|
365
|
+
logger.error(f"注册模块 {name} 时尝试退出进程 (SystemExit({e.code})),已跳过。"
|
|
366
|
+
f"请不要使用 sys.exit() 或 raise SystemExit")
|
|
367
|
+
return False
|
|
358
368
|
except Exception as e:
|
|
359
369
|
logger.error(f"注册模块 {name} 失败: {e}")
|
|
360
370
|
return False
|
|
@@ -368,7 +378,7 @@ class ModuleLoader(BaseLoader):
|
|
|
368
378
|
failed_modules = []
|
|
369
379
|
for i, result in enumerate(register_results):
|
|
370
380
|
module_name = modules[i]
|
|
371
|
-
if isinstance(result,
|
|
381
|
+
if isinstance(result, BaseException) or result is False:
|
|
372
382
|
logger.warning(f"模块 {module_name} 注册失败,已跳过")
|
|
373
383
|
failed_modules.append(module_name)
|
|
374
384
|
|
|
@@ -527,6 +537,9 @@ class ModuleLoader(BaseLoader):
|
|
|
527
537
|
logger.debug(f"挂载立即加载模块到 sdk: {meta_name}")
|
|
528
538
|
else:
|
|
529
539
|
logger.warning(f"立即加载模块 {meta_name} 失败,已跳过")
|
|
540
|
+
except SystemExit as e:
|
|
541
|
+
logger.warning(f"初始化模块 {meta_name} 时尝试退出进程 (SystemExit({e.code})),已跳过。"
|
|
542
|
+
f"请不要使用 sys.exit() 或 raise SystemExit")
|
|
530
543
|
except Exception as e:
|
|
531
544
|
logger.warning(f"初始化模块 {meta_name} 失败,已跳过: {e}")
|
|
532
545
|
|
|
@@ -655,6 +668,17 @@ class LazyModule:
|
|
|
655
668
|
f"懒加载模块 {object.__getattribute__(self, '_module_name')} 初始化完成"
|
|
656
669
|
)
|
|
657
670
|
|
|
671
|
+
except SystemExit as e:
|
|
672
|
+
module_name = object.__getattribute__(self, "_module_name")
|
|
673
|
+
await lifecycle.submit_event(
|
|
674
|
+
"module.init",
|
|
675
|
+
msg=f"模块 {module_name} 尝试退出进程 (SystemExit)",
|
|
676
|
+
data={"module_name": module_name, "success": False},
|
|
677
|
+
)
|
|
678
|
+
logger.error(f"懒加载模块 {module_name} 尝试退出进程 (SystemExit({e.code})),已跳过。"
|
|
679
|
+
f"请不要使用 sys.exit() 或 raise SystemExit")
|
|
680
|
+
object.__setattr__(self, "_initialized", False)
|
|
681
|
+
object.__setattr__(self, "_init_failed", True)
|
|
658
682
|
except Exception as e:
|
|
659
683
|
await lifecycle.submit_event(
|
|
660
684
|
"module.init",
|
|
@@ -730,6 +754,9 @@ class LazyModule:
|
|
|
730
754
|
new_loop = asyncio.new_event_loop()
|
|
731
755
|
try:
|
|
732
756
|
new_loop.run_until_complete(self._initialize())
|
|
757
|
+
except SystemExit as e:
|
|
758
|
+
init_error[0] = e
|
|
759
|
+
object.__setattr__(self, "_init_failed", True)
|
|
733
760
|
except Exception as e:
|
|
734
761
|
init_error[0] = e
|
|
735
762
|
object.__setattr__(self, "_init_failed", True)
|
|
@@ -784,6 +811,13 @@ class LazyModule:
|
|
|
784
811
|
f"懒加载模块 {object.__getattribute__(self, '_module_name')} 同步初始化完成"
|
|
785
812
|
)
|
|
786
813
|
|
|
814
|
+
except SystemExit as e:
|
|
815
|
+
logger.error(
|
|
816
|
+
f"懒加载模块 {object.__getattribute__(self, '_module_name')} 尝试退出进程 "
|
|
817
|
+
f"(SystemExit({e.code})),已跳过。请不要使用 sys.exit() 或 raise SystemExit"
|
|
818
|
+
)
|
|
819
|
+
object.__setattr__(self, "_initialized", False)
|
|
820
|
+
object.__setattr__(self, "_init_failed", True)
|
|
787
821
|
except Exception as e:
|
|
788
822
|
logger.error(
|
|
789
823
|
f"懒加载模块 {object.__getattribute__(self, '_module_name')} 同步初始化失败: {e}"
|
|
@@ -15,6 +15,7 @@ from __future__ import annotations
|
|
|
15
15
|
|
|
16
16
|
import asyncio
|
|
17
17
|
import importlib
|
|
18
|
+
import os
|
|
18
19
|
import sys
|
|
19
20
|
from typing import TYPE_CHECKING
|
|
20
21
|
from .Core.constants import UNINIT_SETTLE_DELAY_SECS, LIFECYCLE_TIMER_CORE_INIT, LIFECYCLE_TIMER_CORE_UNINIT
|
|
@@ -971,6 +972,39 @@ class SDK:
|
|
|
971
972
|
|
|
972
973
|
return True
|
|
973
974
|
|
|
975
|
+
RESTART_EXIT_CODE = 42
|
|
976
|
+
|
|
977
|
+
async def hard_restart(self) -> bool:
|
|
978
|
+
"""
|
|
979
|
+
硬重启:反初始化后退出进程,由父进程(run.py)重新启动新实例
|
|
980
|
+
|
|
981
|
+
与 restart()(热重启)的区别:
|
|
982
|
+
- restart(): 在同一进程内反初始化再重新初始化
|
|
983
|
+
- hard_restart(): 反初始化后退出进程,由父进程重新启动全新进程
|
|
984
|
+
|
|
985
|
+
确保资源完全释放
|
|
986
|
+
|
|
987
|
+
需要通过 epsdk run 启动才生效,否则进程退出后不会自动重启。
|
|
988
|
+
|
|
989
|
+
:return: bool 硬重启任务是否成功调度
|
|
990
|
+
|
|
991
|
+
:example:
|
|
992
|
+
>>> await sdk.hard_restart()
|
|
993
|
+
"""
|
|
994
|
+
|
|
995
|
+
async def _do_hard_restart():
|
|
996
|
+
await asyncio.sleep(0.5)
|
|
997
|
+
try:
|
|
998
|
+
self.logger.info("[HardRestart] 开始硬重启,执行反初始化...")
|
|
999
|
+
await self.uninit()
|
|
1000
|
+
self.logger.info("[HardRestart] 反初始化完成,正在退出进程...")
|
|
1001
|
+
except Exception as e:
|
|
1002
|
+
self.logger.error(f"[HardRestart] 反初始化异常: {e}")
|
|
1003
|
+
os._exit(self.RESTART_EXIT_CODE)
|
|
1004
|
+
|
|
1005
|
+
asyncio.ensure_future(_do_hard_restart())
|
|
1006
|
+
return True
|
|
1007
|
+
|
|
974
1008
|
async def uninit(self) -> bool:
|
|
975
1009
|
"""
|
|
976
1010
|
SDK 反初始化
|
|
@@ -20,6 +20,7 @@ example:
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
import asyncio
|
|
22
22
|
import importlib
|
|
23
|
+
import os
|
|
23
24
|
import sys
|
|
24
25
|
from typing import TYPE_CHECKING
|
|
25
26
|
from .Core.constants import UNINIT_SETTLE_DELAY_SECS, LIFECYCLE_TIMER_CORE_INIT, LIFECYCLE_TIMER_CORE_UNINIT
|
|
@@ -170,6 +171,24 @@ class SDK:
|
|
|
170
171
|
>>> await sdk.restart()
|
|
171
172
|
"""
|
|
172
173
|
...
|
|
174
|
+
async def hard_restart(self: object) -> bool:
|
|
175
|
+
"""
|
|
176
|
+
硬重启:反初始化后退出进程,由父进程(run.py)重新启动新实例
|
|
177
|
+
|
|
178
|
+
与 restart()(热重启)的区别:
|
|
179
|
+
- restart(): 在同一进程内反初始化再重新初始化
|
|
180
|
+
- hard_restart(): 反初始化后退出进程,由父进程重新启动全新进程
|
|
181
|
+
|
|
182
|
+
确保资源完全释放
|
|
183
|
+
|
|
184
|
+
需要通过 epsdk run 启动才生效,否则进程退出后不会自动重启。
|
|
185
|
+
|
|
186
|
+
:return: bool 硬重启任务是否成功调度
|
|
187
|
+
|
|
188
|
+
:example:
|
|
189
|
+
>>> await sdk.hard_restart()
|
|
190
|
+
"""
|
|
191
|
+
...
|
|
173
192
|
async def uninit(self: object) -> bool:
|
|
174
193
|
"""
|
|
175
194
|
SDK 反初始化
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|