@masuidrive/procman 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/src/cli/commands/clear-log.d.ts +10 -0
- package/dist/src/cli/commands/clear-log.d.ts.map +1 -0
- package/dist/src/cli/commands/clear-log.js +77 -0
- package/dist/src/cli/commands/clear-log.js.map +1 -0
- package/dist/src/cli/commands/exit.d.ts +10 -0
- package/dist/src/cli/commands/exit.d.ts.map +1 -0
- package/dist/src/cli/commands/exit.js +65 -0
- package/dist/src/cli/commands/exit.js.map +1 -0
- package/dist/src/cli/commands/help.d.ts +10 -0
- package/dist/src/cli/commands/help.d.ts.map +1 -0
- package/dist/src/cli/commands/help.js +340 -0
- package/dist/src/cli/commands/help.js.map +1 -0
- package/dist/src/cli/commands/list.d.ts +11 -0
- package/dist/src/cli/commands/list.d.ts.map +1 -0
- package/dist/src/cli/commands/list.js +130 -0
- package/dist/src/cli/commands/list.js.map +1 -0
- package/dist/src/cli/commands/load.d.ts +11 -0
- package/dist/src/cli/commands/load.d.ts.map +1 -0
- package/dist/src/cli/commands/load.js +250 -0
- package/dist/src/cli/commands/load.js.map +1 -0
- package/dist/src/cli/commands/log.d.ts +18 -0
- package/dist/src/cli/commands/log.d.ts.map +1 -0
- package/dist/src/cli/commands/log.js +282 -0
- package/dist/src/cli/commands/log.js.map +1 -0
- package/dist/src/cli/commands/restart.d.ts +11 -0
- package/dist/src/cli/commands/restart.d.ts.map +1 -0
- package/dist/src/cli/commands/restart.js +99 -0
- package/dist/src/cli/commands/restart.js.map +1 -0
- package/dist/src/cli/commands/start.d.ts +11 -0
- package/dist/src/cli/commands/start.d.ts.map +1 -0
- package/dist/src/cli/commands/start.js +105 -0
- package/dist/src/cli/commands/start.js.map +1 -0
- package/dist/src/cli/commands/stop.d.ts +12 -0
- package/dist/src/cli/commands/stop.d.ts.map +1 -0
- package/dist/src/cli/commands/stop.js +105 -0
- package/dist/src/cli/commands/stop.js.map +1 -0
- package/dist/src/cli/index.d.ts +3 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/parser.d.ts +14 -0
- package/dist/src/cli/parser.d.ts.map +1 -0
- package/dist/src/cli/parser.js +131 -0
- package/dist/src/cli/parser.js.map +1 -0
- package/dist/src/cli/signal-handler.d.ts +51 -0
- package/dist/src/cli/signal-handler.d.ts.map +1 -0
- package/dist/src/cli/signal-handler.js +129 -0
- package/dist/src/cli/signal-handler.js.map +1 -0
- package/dist/src/cli/utils/error-handler.d.ts +39 -0
- package/dist/src/cli/utils/error-handler.d.ts.map +1 -0
- package/dist/src/cli/utils/error-handler.js +200 -0
- package/dist/src/cli/utils/error-handler.js.map +1 -0
- package/dist/src/cli/utils/error-utils.d.ts +16 -0
- package/dist/src/cli/utils/error-utils.d.ts.map +1 -0
- package/dist/src/cli/utils/error-utils.js +48 -0
- package/dist/src/cli/utils/error-utils.js.map +1 -0
- package/dist/src/cli/utils/ipc-client.d.ts +80 -0
- package/dist/src/cli/utils/ipc-client.d.ts.map +1 -0
- package/dist/src/cli/utils/ipc-client.js +275 -0
- package/dist/src/cli/utils/ipc-client.js.map +1 -0
- package/dist/src/config/config-loader.d.ts +74 -0
- package/dist/src/config/config-loader.d.ts.map +1 -0
- package/dist/src/config/config-loader.js +229 -0
- package/dist/src/config/config-loader.js.map +1 -0
- package/dist/src/config/config-normalizer.d.ts +135 -0
- package/dist/src/config/config-normalizer.d.ts.map +1 -0
- package/dist/src/config/config-normalizer.js +309 -0
- package/dist/src/config/config-normalizer.js.map +1 -0
- package/dist/src/config/config-reporter.d.ts +183 -0
- package/dist/src/config/config-reporter.d.ts.map +1 -0
- package/dist/src/config/config-reporter.js +311 -0
- package/dist/src/config/config-reporter.js.map +1 -0
- package/dist/src/config/config-validator.d.ts +163 -0
- package/dist/src/config/config-validator.d.ts.map +1 -0
- package/dist/src/config/config-validator.js +489 -0
- package/dist/src/config/config-validator.js.map +1 -0
- package/dist/src/config/config-watcher.d.ts +161 -0
- package/dist/src/config/config-watcher.d.ts.map +1 -0
- package/dist/src/config/config-watcher.js +245 -0
- package/dist/src/config/config-watcher.js.map +1 -0
- package/dist/src/config/index.d.ts +36 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +41 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/secure-config-loader.d.ts +77 -0
- package/dist/src/config/secure-config-loader.d.ts.map +1 -0
- package/dist/src/config/secure-config-loader.js +326 -0
- package/dist/src/config/secure-config-loader.js.map +1 -0
- package/dist/src/daemon/base-socket-connection.d.ts +66 -0
- package/dist/src/daemon/base-socket-connection.d.ts.map +1 -0
- package/dist/src/daemon/base-socket-connection.js +192 -0
- package/dist/src/daemon/base-socket-connection.js.map +1 -0
- package/dist/src/daemon/component-manager.d.ts +180 -0
- package/dist/src/daemon/component-manager.d.ts.map +1 -0
- package/dist/src/daemon/component-manager.js +794 -0
- package/dist/src/daemon/component-manager.js.map +1 -0
- package/dist/src/daemon/crash-recovery.d.ts +71 -0
- package/dist/src/daemon/crash-recovery.d.ts.map +1 -0
- package/dist/src/daemon/crash-recovery.js +282 -0
- package/dist/src/daemon/crash-recovery.js.map +1 -0
- package/dist/src/daemon/daemon-main.d.ts +18 -0
- package/dist/src/daemon/daemon-main.d.ts.map +1 -0
- package/dist/src/daemon/daemon-main.js +160 -0
- package/dist/src/daemon/daemon-main.js.map +1 -0
- package/dist/src/daemon/daemon-state-manager.d.ts +111 -0
- package/dist/src/daemon/daemon-state-manager.d.ts.map +1 -0
- package/dist/src/daemon/daemon-state-manager.js +194 -0
- package/dist/src/daemon/daemon-state-manager.js.map +1 -0
- package/dist/src/daemon/data-directory.d.ts +51 -0
- package/dist/src/daemon/data-directory.d.ts.map +1 -0
- package/dist/src/daemon/data-directory.js +136 -0
- package/dist/src/daemon/data-directory.js.map +1 -0
- package/dist/src/daemon/index.d.ts +20 -0
- package/dist/src/daemon/index.d.ts.map +1 -0
- package/dist/src/daemon/index.js +24 -0
- package/dist/src/daemon/index.js.map +1 -0
- package/dist/src/daemon/ipc-client-base.d.ts +153 -0
- package/dist/src/daemon/ipc-client-base.d.ts.map +1 -0
- package/dist/src/daemon/ipc-client-base.js +476 -0
- package/dist/src/daemon/ipc-client-base.js.map +1 -0
- package/dist/src/daemon/ipc-command-handler.d.ts +107 -0
- package/dist/src/daemon/ipc-command-handler.d.ts.map +1 -0
- package/dist/src/daemon/ipc-command-handler.js +483 -0
- package/dist/src/daemon/ipc-command-handler.js.map +1 -0
- package/dist/src/daemon/ipc-factory.d.ts +92 -0
- package/dist/src/daemon/ipc-factory.d.ts.map +1 -0
- package/dist/src/daemon/ipc-factory.js +210 -0
- package/dist/src/daemon/ipc-factory.js.map +1 -0
- package/dist/src/daemon/ipc-server-base.d.ts +158 -0
- package/dist/src/daemon/ipc-server-base.d.ts.map +1 -0
- package/dist/src/daemon/ipc-server-base.js +491 -0
- package/dist/src/daemon/ipc-server-base.js.map +1 -0
- package/dist/src/daemon/message-protocol.d.ts +132 -0
- package/dist/src/daemon/message-protocol.d.ts.map +1 -0
- package/dist/src/daemon/message-protocol.js +252 -0
- package/dist/src/daemon/message-protocol.js.map +1 -0
- package/dist/src/daemon/named-pipe-client.d.ts +61 -0
- package/dist/src/daemon/named-pipe-client.d.ts.map +1 -0
- package/dist/src/daemon/named-pipe-client.js +221 -0
- package/dist/src/daemon/named-pipe-client.js.map +1 -0
- package/dist/src/daemon/named-pipe-server.d.ts +40 -0
- package/dist/src/daemon/named-pipe-server.d.ts.map +1 -0
- package/dist/src/daemon/named-pipe-server.js +102 -0
- package/dist/src/daemon/named-pipe-server.js.map +1 -0
- package/dist/src/daemon/orphan-detector.d.ts +66 -0
- package/dist/src/daemon/orphan-detector.d.ts.map +1 -0
- package/dist/src/daemon/orphan-detector.js +208 -0
- package/dist/src/daemon/orphan-detector.js.map +1 -0
- package/dist/src/daemon/pid-manager.d.ts +49 -0
- package/dist/src/daemon/pid-manager.d.ts.map +1 -0
- package/dist/src/daemon/pid-manager.js +110 -0
- package/dist/src/daemon/pid-manager.js.map +1 -0
- package/dist/src/daemon/procman-daemon.d.ts +188 -0
- package/dist/src/daemon/procman-daemon.d.ts.map +1 -0
- package/dist/src/daemon/procman-daemon.js +802 -0
- package/dist/src/daemon/procman-daemon.js.map +1 -0
- package/dist/src/daemon/reconnection-system.d.ts +113 -0
- package/dist/src/daemon/reconnection-system.d.ts.map +1 -0
- package/dist/src/daemon/reconnection-system.js +223 -0
- package/dist/src/daemon/reconnection-system.js.map +1 -0
- package/dist/src/daemon/resource-manager.d.ts +204 -0
- package/dist/src/daemon/resource-manager.d.ts.map +1 -0
- package/dist/src/daemon/resource-manager.js +423 -0
- package/dist/src/daemon/resource-manager.js.map +1 -0
- package/dist/src/daemon/signal-handler.d.ts +58 -0
- package/dist/src/daemon/signal-handler.d.ts.map +1 -0
- package/dist/src/daemon/signal-handler.js +142 -0
- package/dist/src/daemon/signal-handler.js.map +1 -0
- package/dist/src/daemon/simple-resource-manager.d.ts +95 -0
- package/dist/src/daemon/simple-resource-manager.d.ts.map +1 -0
- package/dist/src/daemon/simple-resource-manager.js +180 -0
- package/dist/src/daemon/simple-resource-manager.js.map +1 -0
- package/dist/src/daemon/unix-socket-client.d.ts +69 -0
- package/dist/src/daemon/unix-socket-client.d.ts.map +1 -0
- package/dist/src/daemon/unix-socket-client.js +313 -0
- package/dist/src/daemon/unix-socket-client.js.map +1 -0
- package/dist/src/daemon/unix-socket-server.d.ts +61 -0
- package/dist/src/daemon/unix-socket-server.d.ts.map +1 -0
- package/dist/src/daemon/unix-socket-server.js +262 -0
- package/dist/src/daemon/unix-socket-server.js.map +1 -0
- package/dist/src/daemon/zombie-reaper.d.ts +83 -0
- package/dist/src/daemon/zombie-reaper.d.ts.map +1 -0
- package/dist/src/daemon/zombie-reaper.js +278 -0
- package/dist/src/daemon/zombie-reaper.js.map +1 -0
- package/dist/src/process-manager/index.d.ts +13 -0
- package/dist/src/process-manager/index.d.ts.map +1 -0
- package/dist/src/process-manager/index.js +11 -0
- package/dist/src/process-manager/index.js.map +1 -0
- package/dist/src/process-manager/interfaces/index.d.ts +31 -0
- package/dist/src/process-manager/interfaces/index.d.ts.map +1 -0
- package/dist/src/process-manager/interfaces/index.js +14 -0
- package/dist/src/process-manager/interfaces/index.js.map +1 -0
- package/dist/src/process-manager/interfaces/process-group.d.ts +200 -0
- package/dist/src/process-manager/interfaces/process-group.d.ts.map +1 -0
- package/dist/src/process-manager/interfaces/process-group.js +10 -0
- package/dist/src/process-manager/interfaces/process-group.js.map +1 -0
- package/dist/src/process-manager/interfaces/process-lifecycle.d.ts +97 -0
- package/dist/src/process-manager/interfaces/process-lifecycle.d.ts.map +1 -0
- package/dist/src/process-manager/interfaces/process-lifecycle.js +10 -0
- package/dist/src/process-manager/interfaces/process-lifecycle.js.map +1 -0
- package/dist/src/process-manager/interfaces/process-monitor.d.ts +118 -0
- package/dist/src/process-manager/interfaces/process-monitor.d.ts.map +1 -0
- package/dist/src/process-manager/interfaces/process-monitor.js +10 -0
- package/dist/src/process-manager/interfaces/process-monitor.js.map +1 -0
- package/dist/src/process-manager/interfaces/process-persistence.d.ts +125 -0
- package/dist/src/process-manager/interfaces/process-persistence.d.ts.map +1 -0
- package/dist/src/process-manager/interfaces/process-persistence.js +10 -0
- package/dist/src/process-manager/interfaces/process-persistence.js.map +1 -0
- package/dist/src/process-manager/managed-process-info.d.ts +307 -0
- package/dist/src/process-manager/managed-process-info.d.ts.map +1 -0
- package/dist/src/process-manager/managed-process-info.js +650 -0
- package/dist/src/process-manager/managed-process-info.js.map +1 -0
- package/dist/src/process-manager/process-group-manager.d.ts +103 -0
- package/dist/src/process-manager/process-group-manager.d.ts.map +1 -0
- package/dist/src/process-manager/process-group-manager.js +400 -0
- package/dist/src/process-manager/process-group-manager.js.map +1 -0
- package/dist/src/process-manager/process-lifecycle-manager.d.ts +68 -0
- package/dist/src/process-manager/process-lifecycle-manager.d.ts.map +1 -0
- package/dist/src/process-manager/process-lifecycle-manager.js +372 -0
- package/dist/src/process-manager/process-lifecycle-manager.js.map +1 -0
- package/dist/src/process-manager/process-manager.d.ts +296 -0
- package/dist/src/process-manager/process-manager.d.ts.map +1 -0
- package/dist/src/process-manager/process-manager.js +659 -0
- package/dist/src/process-manager/process-manager.js.map +1 -0
- package/dist/src/process-manager/process-monitor.d.ts +95 -0
- package/dist/src/process-manager/process-monitor.d.ts.map +1 -0
- package/dist/src/process-manager/process-monitor.js +357 -0
- package/dist/src/process-manager/process-monitor.js.map +1 -0
- package/dist/src/process-manager/process-persistence.d.ts +68 -0
- package/dist/src/process-manager/process-persistence.d.ts.map +1 -0
- package/dist/src/process-manager/process-persistence.js +364 -0
- package/dist/src/process-manager/process-persistence.js.map +1 -0
- package/dist/src/process-manager/utils/mutex.d.ts +82 -0
- package/dist/src/process-manager/utils/mutex.d.ts.map +1 -0
- package/dist/src/process-manager/utils/mutex.js +172 -0
- package/dist/src/process-manager/utils/mutex.js.map +1 -0
- package/dist/src/services/index.d.ts +8 -0
- package/dist/src/services/index.d.ts.map +1 -0
- package/dist/src/services/index.js +8 -0
- package/dist/src/services/index.js.map +1 -0
- package/dist/src/services/log-manager-config.d.ts +65 -0
- package/dist/src/services/log-manager-config.d.ts.map +1 -0
- package/dist/src/services/log-manager-config.js +145 -0
- package/dist/src/services/log-manager-config.js.map +1 -0
- package/dist/src/services/log-manager-factory.d.ts +134 -0
- package/dist/src/services/log-manager-factory.d.ts.map +1 -0
- package/dist/src/services/log-manager-factory.js +203 -0
- package/dist/src/services/log-manager-factory.js.map +1 -0
- package/dist/src/services/log-manager.d.ts +170 -0
- package/dist/src/services/log-manager.d.ts.map +1 -0
- package/dist/src/services/log-manager.js +1199 -0
- package/dist/src/services/log-manager.js.map +1 -0
- package/dist/src/services/log-path-validator.d.ts +121 -0
- package/dist/src/services/log-path-validator.d.ts.map +1 -0
- package/dist/src/services/log-path-validator.js +302 -0
- package/dist/src/services/log-path-validator.js.map +1 -0
- package/dist/src/services/process-log-integration.d.ts +62 -0
- package/dist/src/services/process-log-integration.d.ts.map +1 -0
- package/dist/src/services/process-log-integration.js +157 -0
- package/dist/src/services/process-log-integration.js.map +1 -0
- package/dist/src/shared/config.d.ts +67 -0
- package/dist/src/shared/config.d.ts.map +1 -0
- package/dist/src/shared/config.js +92 -0
- package/dist/src/shared/config.js.map +1 -0
- package/dist/src/shared/constants-streaming.d.ts +39 -0
- package/dist/src/shared/constants-streaming.d.ts.map +1 -0
- package/dist/src/shared/constants-streaming.js +39 -0
- package/dist/src/shared/constants-streaming.js.map +1 -0
- package/dist/src/shared/constants.d.ts +60 -0
- package/dist/src/shared/constants.d.ts.map +1 -0
- package/dist/src/shared/constants.js +71 -0
- package/dist/src/shared/constants.js.map +1 -0
- package/dist/src/shared/errors.d.ts +70 -0
- package/dist/src/shared/errors.d.ts.map +1 -0
- package/dist/src/shared/errors.js +101 -0
- package/dist/src/shared/errors.js.map +1 -0
- package/dist/src/shared/index.d.ts +14 -0
- package/dist/src/shared/index.d.ts.map +1 -0
- package/dist/src/shared/index.js +22 -0
- package/dist/src/shared/index.js.map +1 -0
- package/dist/src/shared/ipc.d.ts +402 -0
- package/dist/src/shared/ipc.d.ts.map +1 -0
- package/dist/src/shared/ipc.js +85 -0
- package/dist/src/shared/ipc.js.map +1 -0
- package/dist/src/shared/logger.d.ts +38 -0
- package/dist/src/shared/logger.d.ts.map +1 -0
- package/dist/src/shared/logger.js +139 -0
- package/dist/src/shared/logger.js.map +1 -0
- package/dist/src/shared/logs.d.ts +53 -0
- package/dist/src/shared/logs.d.ts.map +1 -0
- package/dist/src/shared/logs.js +26 -0
- package/dist/src/shared/logs.js.map +1 -0
- package/dist/src/shared/process.d.ts +102 -0
- package/dist/src/shared/process.d.ts.map +1 -0
- package/dist/src/shared/process.js +55 -0
- package/dist/src/shared/process.js.map +1 -0
- package/dist/src/shared/types.d.ts +15 -0
- package/dist/src/shared/types.d.ts.map +1 -0
- package/dist/src/shared/types.js +8 -0
- package/dist/src/shared/types.js.map +1 -0
- package/dist/src/types/index.d.ts +19 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +5 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/utils/event-cleanup.d.ts +30 -0
- package/dist/src/utils/event-cleanup.d.ts.map +1 -0
- package/dist/src/utils/event-cleanup.js +32 -0
- package/dist/src/utils/event-cleanup.js.map +1 -0
- package/dist/src/utils/memory/memory-monitor.d.ts +126 -0
- package/dist/src/utils/memory/memory-monitor.d.ts.map +1 -0
- package/dist/src/utils/memory/memory-monitor.js +246 -0
- package/dist/src/utils/memory/memory-monitor.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,794 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Manager - コンポーネント管理の専門クラス
|
|
3
|
+
*
|
|
4
|
+
* デーモンの各コンポーネントの初期化・クリーンアップを管理する。
|
|
5
|
+
* Single Responsibility Principle に従ってコンポーネント管理のみに特化。
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import { EventCleanupHelper } from '../utils/event-cleanup.js';
|
|
9
|
+
import { ConfigLoader } from '../config/config-loader.js';
|
|
10
|
+
import { ProcessManager } from '../process-manager/process-manager.js';
|
|
11
|
+
import { LogManager } from '../services/log-manager.js';
|
|
12
|
+
import { createIPCServer } from './ipc-factory.js';
|
|
13
|
+
import { IPCCommandHandler } from './ipc-command-handler.js';
|
|
14
|
+
import { LOG_STREAM_EVENTS, STREAM_CONFIG, STREAM_MESSAGE_TYPES, } from '../shared/constants-streaming.js';
|
|
15
|
+
/**
|
|
16
|
+
* Component initialization error
|
|
17
|
+
*/
|
|
18
|
+
export class ComponentInitializationError extends Error {
|
|
19
|
+
componentName;
|
|
20
|
+
originalError;
|
|
21
|
+
constructor(componentName, originalError) {
|
|
22
|
+
super(`Failed to initialize component '${componentName}': ${originalError.message}`);
|
|
23
|
+
this.componentName = componentName;
|
|
24
|
+
this.originalError = originalError;
|
|
25
|
+
this.name = 'ComponentInitializationError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Component cleanup error
|
|
30
|
+
*/
|
|
31
|
+
export class ComponentCleanupError extends Error {
|
|
32
|
+
componentName;
|
|
33
|
+
originalError;
|
|
34
|
+
constructor(componentName, originalError) {
|
|
35
|
+
super(`Failed to cleanup component '${componentName}': ${originalError.message}`);
|
|
36
|
+
this.componentName = componentName;
|
|
37
|
+
this.originalError = originalError;
|
|
38
|
+
this.name = 'ComponentCleanupError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Component manager class
|
|
43
|
+
*
|
|
44
|
+
* Manages the lifecycle of all daemon components with proper error handling
|
|
45
|
+
* and rollback capabilities.
|
|
46
|
+
*/
|
|
47
|
+
export class ComponentManager extends EventEmitter {
|
|
48
|
+
dataDirectory;
|
|
49
|
+
components = new Map();
|
|
50
|
+
initializationOrder = [];
|
|
51
|
+
cleanupOrder = [];
|
|
52
|
+
initializationErrors = [];
|
|
53
|
+
// Component instances
|
|
54
|
+
configLoader;
|
|
55
|
+
processManager;
|
|
56
|
+
logManager;
|
|
57
|
+
ipcServer;
|
|
58
|
+
commandHandler;
|
|
59
|
+
// Add EventCleanupHelper for proper listener cleanup
|
|
60
|
+
listenerCleanup = new EventCleanupHelper();
|
|
61
|
+
constructor(dataDirectory) {
|
|
62
|
+
super();
|
|
63
|
+
this.dataDirectory = dataDirectory;
|
|
64
|
+
// No initialization needed for EventCleanupHelper
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Private method to register and track listeners
|
|
68
|
+
*/
|
|
69
|
+
registerListener(emitter, event, listener) {
|
|
70
|
+
this.listenerCleanup.track(emitter, event, listener);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Initialize all components
|
|
74
|
+
*/
|
|
75
|
+
async initializeAll() {
|
|
76
|
+
this.initializationErrors = [];
|
|
77
|
+
const startTime = Date.now();
|
|
78
|
+
try {
|
|
79
|
+
console.log('Starting daemon component initialization...');
|
|
80
|
+
// Initialize components in order with progress logging
|
|
81
|
+
console.log('Initializing ConfigLoader...');
|
|
82
|
+
await this.initializeConfigLoader();
|
|
83
|
+
console.log('ConfigLoader initialized successfully');
|
|
84
|
+
console.log('Initializing ProcessManager...');
|
|
85
|
+
await this.initializeProcessManager();
|
|
86
|
+
console.log('ProcessManager initialized successfully');
|
|
87
|
+
console.log('Initializing LogManager...');
|
|
88
|
+
await this.initializeLogManager();
|
|
89
|
+
console.log('LogManager initialized successfully');
|
|
90
|
+
console.log('Initializing IPCServer...');
|
|
91
|
+
await this.initializeIPCServer();
|
|
92
|
+
console.log('IPCServer initialized successfully');
|
|
93
|
+
console.log('Initializing CommandHandler...');
|
|
94
|
+
await this.initializeCommandHandler();
|
|
95
|
+
console.log('CommandHandler initialized successfully');
|
|
96
|
+
const totalTime = Date.now() - startTime;
|
|
97
|
+
console.log(`All daemon components initialized successfully in ${totalTime}ms`);
|
|
98
|
+
this.emit('allComponentsStarted');
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const totalTime = Date.now() - startTime;
|
|
102
|
+
console.error(`Component initialization failed after ${totalTime}ms:`, error);
|
|
103
|
+
// Rollback any initialized components
|
|
104
|
+
await this.rollbackInitialization();
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Cleanup all components
|
|
110
|
+
*/
|
|
111
|
+
async cleanupAll() {
|
|
112
|
+
const errors = [];
|
|
113
|
+
// Cleanup all streaming sessions first
|
|
114
|
+
this.cleanupAllStreamingSessions();
|
|
115
|
+
// Cleanup in reverse order of initialization
|
|
116
|
+
const componentsToCleanup = [...this.cleanupOrder].reverse();
|
|
117
|
+
for (const componentName of componentsToCleanup) {
|
|
118
|
+
try {
|
|
119
|
+
const component = this.components.get(componentName);
|
|
120
|
+
if (component && component.isInitialized()) {
|
|
121
|
+
await component.cleanup();
|
|
122
|
+
this.emit('componentStopped', componentName);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const cleanupError = new ComponentCleanupError(componentName, error);
|
|
127
|
+
errors.push(cleanupError);
|
|
128
|
+
this.emit('componentError', componentName, cleanupError);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Clear component references
|
|
132
|
+
this.clearComponents();
|
|
133
|
+
// Clean up listener management (after streaming sessions are already cleaned up)
|
|
134
|
+
await this.cleanupListeners();
|
|
135
|
+
this.emit('allComponentsStopped');
|
|
136
|
+
// Throw aggregated errors if any occurred
|
|
137
|
+
if (errors.length > 0) {
|
|
138
|
+
const errorMessage = `Component cleanup failed: ${errors.map((e) => e.message).join('; ')}`;
|
|
139
|
+
throw new Error(errorMessage);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get component by name
|
|
144
|
+
*/
|
|
145
|
+
getComponent(name) {
|
|
146
|
+
switch (name) {
|
|
147
|
+
case 'configLoader':
|
|
148
|
+
return this.configLoader;
|
|
149
|
+
case 'processManager':
|
|
150
|
+
return this.processManager;
|
|
151
|
+
case 'logManager':
|
|
152
|
+
return this.logManager;
|
|
153
|
+
case 'ipcServer':
|
|
154
|
+
return this.ipcServer;
|
|
155
|
+
case 'commandHandler':
|
|
156
|
+
return this.commandHandler;
|
|
157
|
+
default:
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Check if all components are initialized
|
|
163
|
+
*/
|
|
164
|
+
areAllComponentsInitialized() {
|
|
165
|
+
return Array.from(this.components.values()).every((component) => component.isInitialized());
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Perform comprehensive health checks on all components
|
|
169
|
+
* Verifies each component is not just initialized but actually functional
|
|
170
|
+
*/
|
|
171
|
+
async performHealthChecks() {
|
|
172
|
+
const details = {};
|
|
173
|
+
let allHealthy = true;
|
|
174
|
+
// Check ConfigLoader health
|
|
175
|
+
if (this.configLoader) {
|
|
176
|
+
try {
|
|
177
|
+
// ConfigLoader is healthy if it exists and can load configuration
|
|
178
|
+
// Since there's no isInitialized method, assume healthy if instance exists
|
|
179
|
+
const isReady = true;
|
|
180
|
+
details.configLoader = {
|
|
181
|
+
status: isReady ? 'healthy' : 'unhealthy',
|
|
182
|
+
message: isReady
|
|
183
|
+
? 'ConfigLoader is ready'
|
|
184
|
+
: 'ConfigLoader not initialized',
|
|
185
|
+
};
|
|
186
|
+
if (!isReady)
|
|
187
|
+
allHealthy = false;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
details.configLoader = {
|
|
191
|
+
status: 'unhealthy',
|
|
192
|
+
message: `ConfigLoader error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
193
|
+
};
|
|
194
|
+
allHealthy = false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
details.configLoader = {
|
|
199
|
+
status: 'unhealthy',
|
|
200
|
+
message: 'ConfigLoader not available',
|
|
201
|
+
};
|
|
202
|
+
allHealthy = false;
|
|
203
|
+
}
|
|
204
|
+
// Check ProcessManager health
|
|
205
|
+
if (this.processManager) {
|
|
206
|
+
try {
|
|
207
|
+
// ProcessManager is healthy if it exists and is properly initialized
|
|
208
|
+
// Since there's no isRunning method, assume healthy if instance exists
|
|
209
|
+
const isReady = true;
|
|
210
|
+
details.processManager = {
|
|
211
|
+
status: isReady ? 'healthy' : 'unhealthy',
|
|
212
|
+
message: isReady
|
|
213
|
+
? 'ProcessManager is running'
|
|
214
|
+
: 'ProcessManager not running',
|
|
215
|
+
};
|
|
216
|
+
if (!isReady)
|
|
217
|
+
allHealthy = false;
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
details.processManager = {
|
|
221
|
+
status: 'unhealthy',
|
|
222
|
+
message: `ProcessManager error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
223
|
+
};
|
|
224
|
+
allHealthy = false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
details.processManager = {
|
|
229
|
+
status: 'unhealthy',
|
|
230
|
+
message: 'ProcessManager not available',
|
|
231
|
+
};
|
|
232
|
+
allHealthy = false;
|
|
233
|
+
}
|
|
234
|
+
// Check LogManager health
|
|
235
|
+
if (this.logManager) {
|
|
236
|
+
try {
|
|
237
|
+
// LogManager is healthy if it exists and is properly initialized
|
|
238
|
+
// Since there's no isRunning method, assume healthy if instance exists
|
|
239
|
+
const isReady = true;
|
|
240
|
+
details.logManager = {
|
|
241
|
+
status: isReady ? 'healthy' : 'unhealthy',
|
|
242
|
+
message: isReady ? 'LogManager is running' : 'LogManager not running',
|
|
243
|
+
};
|
|
244
|
+
if (!isReady)
|
|
245
|
+
allHealthy = false;
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
details.logManager = {
|
|
249
|
+
status: 'unhealthy',
|
|
250
|
+
message: `LogManager error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
251
|
+
};
|
|
252
|
+
allHealthy = false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
details.logManager = {
|
|
257
|
+
status: 'unhealthy',
|
|
258
|
+
message: 'LogManager not available',
|
|
259
|
+
};
|
|
260
|
+
allHealthy = false;
|
|
261
|
+
}
|
|
262
|
+
// Check IPCServer health - most critical for readiness
|
|
263
|
+
if (this.ipcServer) {
|
|
264
|
+
try {
|
|
265
|
+
const isListening = this.ipcServer.isServerListening?.();
|
|
266
|
+
details.ipcServer = {
|
|
267
|
+
status: isListening ? 'healthy' : 'unhealthy',
|
|
268
|
+
message: isListening
|
|
269
|
+
? 'IPC Server is listening and ready'
|
|
270
|
+
: 'IPC Server not listening',
|
|
271
|
+
};
|
|
272
|
+
if (!isListening)
|
|
273
|
+
allHealthy = false;
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
details.ipcServer = {
|
|
277
|
+
status: 'unhealthy',
|
|
278
|
+
message: `IPCServer error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
279
|
+
};
|
|
280
|
+
allHealthy = false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
details.ipcServer = {
|
|
285
|
+
status: 'unhealthy',
|
|
286
|
+
message: 'IPC Server not available',
|
|
287
|
+
};
|
|
288
|
+
allHealthy = false;
|
|
289
|
+
}
|
|
290
|
+
// Check CommandHandler health
|
|
291
|
+
if (this.commandHandler) {
|
|
292
|
+
try {
|
|
293
|
+
// CommandHandler is healthy if it exists (no specific health check method)
|
|
294
|
+
details.commandHandler = {
|
|
295
|
+
status: 'healthy',
|
|
296
|
+
message: 'CommandHandler is ready',
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
details.commandHandler = {
|
|
301
|
+
status: 'unhealthy',
|
|
302
|
+
message: `CommandHandler error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
303
|
+
};
|
|
304
|
+
allHealthy = false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
details.commandHandler = {
|
|
309
|
+
status: 'unhealthy',
|
|
310
|
+
message: 'CommandHandler not available',
|
|
311
|
+
};
|
|
312
|
+
allHealthy = false;
|
|
313
|
+
}
|
|
314
|
+
return { healthy: allHealthy, details };
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Get initialization errors
|
|
318
|
+
*/
|
|
319
|
+
getInitializationErrors() {
|
|
320
|
+
return [...this.initializationErrors];
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Initialize config loader
|
|
324
|
+
*/
|
|
325
|
+
async initializeConfigLoader() {
|
|
326
|
+
try {
|
|
327
|
+
this.configLoader = new ConfigLoader();
|
|
328
|
+
await this.registerComponent('configLoader', this.configLoader);
|
|
329
|
+
this.emit('componentStarted', 'configLoader');
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
const initError = new ComponentInitializationError('configLoader', error);
|
|
333
|
+
this.initializationErrors.push(initError);
|
|
334
|
+
this.emit('componentError', 'configLoader', initError);
|
|
335
|
+
throw initError;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Initialize process manager
|
|
340
|
+
*/
|
|
341
|
+
async initializeProcessManager() {
|
|
342
|
+
try {
|
|
343
|
+
this.processManager = ProcessManager.create();
|
|
344
|
+
await this.registerComponent('processManager', this.processManager);
|
|
345
|
+
this.emit('componentStarted', 'processManager');
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
const initError = new ComponentInitializationError('processManager', error);
|
|
349
|
+
this.initializationErrors.push(initError);
|
|
350
|
+
this.emit('componentError', 'processManager', initError);
|
|
351
|
+
throw initError;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Initialize log manager
|
|
356
|
+
*/
|
|
357
|
+
async initializeLogManager() {
|
|
358
|
+
try {
|
|
359
|
+
const logDir = await this.dataDirectory.getLogDirectory();
|
|
360
|
+
this.logManager = new LogManager(logDir);
|
|
361
|
+
await this.registerComponent('logManager', this.logManager);
|
|
362
|
+
this.emit('componentStarted', 'logManager');
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
const initError = new ComponentInitializationError('logManager', error);
|
|
366
|
+
this.initializationErrors.push(initError);
|
|
367
|
+
this.emit('componentError', 'logManager', initError);
|
|
368
|
+
throw initError;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Initialize IPC server
|
|
373
|
+
*/
|
|
374
|
+
async initializeIPCServer() {
|
|
375
|
+
try {
|
|
376
|
+
const startTime = Date.now();
|
|
377
|
+
console.log('Getting socket path...');
|
|
378
|
+
const socketPath = await this.dataDirectory.getSocketPath();
|
|
379
|
+
console.log(`Socket path resolved: ${socketPath}`);
|
|
380
|
+
console.log('Creating IPC server...');
|
|
381
|
+
this.ipcServer = createIPCServer({ path: socketPath });
|
|
382
|
+
console.log('Registering IPC server component...');
|
|
383
|
+
await this.registerComponent('ipcServer', this.ipcServer);
|
|
384
|
+
const totalTime = Date.now() - startTime;
|
|
385
|
+
console.log(`IPC server initialized in ${totalTime}ms`);
|
|
386
|
+
this.emit('componentStarted', 'ipcServer');
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
console.error('IPC server initialization failed:', error);
|
|
390
|
+
const initError = new ComponentInitializationError('ipcServer', error);
|
|
391
|
+
this.initializationErrors.push(initError);
|
|
392
|
+
this.emit('componentError', 'ipcServer', initError);
|
|
393
|
+
throw initError;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Initialize command handler
|
|
398
|
+
*/
|
|
399
|
+
async initializeCommandHandler() {
|
|
400
|
+
try {
|
|
401
|
+
if (!this.configLoader ||
|
|
402
|
+
!this.processManager ||
|
|
403
|
+
!this.logManager ||
|
|
404
|
+
!this.ipcServer) {
|
|
405
|
+
throw new Error('Required components not initialized');
|
|
406
|
+
}
|
|
407
|
+
// Create a mock daemon object for the command handler
|
|
408
|
+
const daemonInterface = this.createDaemonInterface();
|
|
409
|
+
this.commandHandler = new IPCCommandHandler(daemonInterface);
|
|
410
|
+
await this.registerComponent('commandHandler', this.commandHandler);
|
|
411
|
+
// Register command handlers with IPC server
|
|
412
|
+
this.registerCommandHandlers();
|
|
413
|
+
this.emit('componentStarted', 'commandHandler');
|
|
414
|
+
}
|
|
415
|
+
catch (error) {
|
|
416
|
+
const initError = new ComponentInitializationError('commandHandler', error);
|
|
417
|
+
this.initializationErrors.push(initError);
|
|
418
|
+
this.emit('componentError', 'commandHandler', initError);
|
|
419
|
+
throw initError;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Create daemon interface for command handler
|
|
424
|
+
*/
|
|
425
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
426
|
+
createDaemonInterface() {
|
|
427
|
+
return {
|
|
428
|
+
getConfigLoader: () => this.configLoader,
|
|
429
|
+
getProcessManager: () => this.processManager,
|
|
430
|
+
getLogManager: () => this.logManager,
|
|
431
|
+
getAllProcessStatuses: async () => {
|
|
432
|
+
// Implementation moved from ProcmanDaemon
|
|
433
|
+
const processInfos = this.processManager.getAllProcessInfo();
|
|
434
|
+
const statusPromises = processInfos.map(async (processInfo) => {
|
|
435
|
+
const info = processInfo;
|
|
436
|
+
if (!info)
|
|
437
|
+
return null;
|
|
438
|
+
// Get process stats from monitor
|
|
439
|
+
const stats = await this.processManager.monitor.getProcessStats(info.name);
|
|
440
|
+
return {
|
|
441
|
+
name: info.name,
|
|
442
|
+
namespace: info.namespace || 'default',
|
|
443
|
+
pid: info.pid,
|
|
444
|
+
status: info.status,
|
|
445
|
+
uptime: info.uptime,
|
|
446
|
+
memory: stats?.memory || 0,
|
|
447
|
+
cpu: stats?.cpu || 0,
|
|
448
|
+
restarts: info.restarts,
|
|
449
|
+
};
|
|
450
|
+
});
|
|
451
|
+
const results = await Promise.all(statusPromises);
|
|
452
|
+
return results.filter((result) => result !== null);
|
|
453
|
+
},
|
|
454
|
+
getConfig: () => {
|
|
455
|
+
// This will be set by the calling code
|
|
456
|
+
return undefined;
|
|
457
|
+
},
|
|
458
|
+
loadConfig: async (configFilePath) => {
|
|
459
|
+
const config = await this.configLoader.load(configFilePath);
|
|
460
|
+
// Stop all existing processes
|
|
461
|
+
const allProcesses = this.processManager.getAllProcessInfo();
|
|
462
|
+
if (allProcesses.length > 0) {
|
|
463
|
+
const processNames = allProcesses
|
|
464
|
+
.map((processInfo) => {
|
|
465
|
+
const info = processInfo;
|
|
466
|
+
return info?.name || '';
|
|
467
|
+
})
|
|
468
|
+
.filter((name) => name !== '');
|
|
469
|
+
await this.processManager.stopProcesses(processNames);
|
|
470
|
+
}
|
|
471
|
+
// Configure new processes
|
|
472
|
+
for (const app of config.apps) {
|
|
473
|
+
this.processManager.configureProcess(app);
|
|
474
|
+
// Setup log manager for this app if log files are configured
|
|
475
|
+
if (this.logManager &&
|
|
476
|
+
(app.log_file || app.out_file || app.error_file)) {
|
|
477
|
+
await this.logManager.setupAppLogs(app.name, {
|
|
478
|
+
logFile: app.log_file,
|
|
479
|
+
outFile: app.out_file,
|
|
480
|
+
errorFile: app.error_file,
|
|
481
|
+
namespace: app.namespace,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return config.apps;
|
|
486
|
+
},
|
|
487
|
+
stop: async () => {
|
|
488
|
+
await this.cleanupAll();
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Register command handlers with IPC server
|
|
494
|
+
*/
|
|
495
|
+
registerCommandHandlers() {
|
|
496
|
+
if (!this.ipcServer || !this.commandHandler) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const commandTypes = [
|
|
500
|
+
'load',
|
|
501
|
+
'start',
|
|
502
|
+
'stop',
|
|
503
|
+
'restart',
|
|
504
|
+
'list',
|
|
505
|
+
'log',
|
|
506
|
+
'clear-log',
|
|
507
|
+
'exit',
|
|
508
|
+
];
|
|
509
|
+
for (const commandType of commandTypes) {
|
|
510
|
+
this.ipcServer.registerHandler(commandType, async (message, connection) => {
|
|
511
|
+
// Pass connection info to command handler for log streaming
|
|
512
|
+
return this.commandHandler.handleMessage(message, connection);
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
// ログストリーミングのセットアップ
|
|
516
|
+
this.setupLogStreaming();
|
|
517
|
+
}
|
|
518
|
+
// ストリーミングセッション管理用のマップ
|
|
519
|
+
// Map to track active streaming sessions with connection info
|
|
520
|
+
streamingSessions = new Map();
|
|
521
|
+
/**
|
|
522
|
+
* Setup log streaming functionality
|
|
523
|
+
*/
|
|
524
|
+
setupLogStreaming() {
|
|
525
|
+
if (!this.commandHandler || !this.ipcServer || !this.logManager) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
// コマンドハンドラーからのログストリーミング開始イベントをリッスン
|
|
529
|
+
// Note: We need connectionId to send logs to specific client only
|
|
530
|
+
// This requires passing connectionId from IPCServer through IPCCommandHandler
|
|
531
|
+
this.registerListener(this.commandHandler, LOG_STREAM_EVENTS.START_LOG_STREAM,
|
|
532
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
533
|
+
(streamConfig) => {
|
|
534
|
+
const { messageId, target, connectionId } = streamConfig;
|
|
535
|
+
const sessionId = `${STREAM_CONFIG.SESSION_PREFIX}-${messageId}-${Date.now()}`;
|
|
536
|
+
// 既存のセッションがあれば停止
|
|
537
|
+
this.stopLogStream(sessionId);
|
|
538
|
+
// Get specific connection instead of all connections
|
|
539
|
+
const connection = connectionId
|
|
540
|
+
? this.ipcServer.getConnection(connectionId)
|
|
541
|
+
: null;
|
|
542
|
+
if (!connection) {
|
|
543
|
+
console.error(`Cannot start log streaming: connection ${connectionId} not found`);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
// ログマネージャーでストリーミングを開始
|
|
547
|
+
const cleanup = this.logManager.startLogStream(target, (logEntry) => {
|
|
548
|
+
// 新しいログエントリを受信したら特定のIPCクライアントに送信
|
|
549
|
+
const streamMessage = {
|
|
550
|
+
id: `${STREAM_CONFIG.SESSION_PREFIX}-${Date.now()}`,
|
|
551
|
+
type: STREAM_MESSAGE_TYPES.LOG_STREAM,
|
|
552
|
+
payload: {
|
|
553
|
+
entry: logEntry,
|
|
554
|
+
app: logEntry.app,
|
|
555
|
+
namespace: logEntry.namespace || 'default',
|
|
556
|
+
},
|
|
557
|
+
timestamp: Date.now(),
|
|
558
|
+
sessionId, // セッションIDを追加
|
|
559
|
+
};
|
|
560
|
+
// 特定の接続にのみメッセージを送信
|
|
561
|
+
try {
|
|
562
|
+
// IPCサーバーの送信メソッドを使用
|
|
563
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
564
|
+
connection.send(JSON.stringify(streamMessage) + '\n');
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
console.error('Failed to send log stream message:', error);
|
|
568
|
+
// エラーが発生した接続のストリーミングを停止
|
|
569
|
+
this.stopLogStream(sessionId);
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
// クリーンアップ関数とconnection情報を保存
|
|
573
|
+
this.streamingSessions.set(sessionId, {
|
|
574
|
+
cleanup,
|
|
575
|
+
connectionId: connectionId || '',
|
|
576
|
+
messageId,
|
|
577
|
+
});
|
|
578
|
+
// 接続が切断された時にストリーミングを停止
|
|
579
|
+
this.setupStreamCleanupOnDisconnect(sessionId);
|
|
580
|
+
});
|
|
581
|
+
// stop-log-streamイベントのリスナーを追加
|
|
582
|
+
this.registerListener(this.commandHandler, LOG_STREAM_EVENTS.STOP_LOG_STREAM,
|
|
583
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
584
|
+
(config) => {
|
|
585
|
+
const { sessionId } = config;
|
|
586
|
+
this.stopLogStream(sessionId);
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Stop log streaming for a specific session
|
|
591
|
+
*/
|
|
592
|
+
stopLogStream(sessionId) {
|
|
593
|
+
const sessionInfo = this.streamingSessions.get(sessionId);
|
|
594
|
+
if (sessionInfo) {
|
|
595
|
+
sessionInfo.cleanup();
|
|
596
|
+
this.streamingSessions.delete(sessionId);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Setup cleanup when connection disconnects
|
|
601
|
+
*/
|
|
602
|
+
setupStreamCleanupOnDisconnect(sessionId) {
|
|
603
|
+
// IPCサーバーの切断イベントを監視
|
|
604
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
605
|
+
const disconnectHandler = () => {
|
|
606
|
+
// 該当するセッションのストリーミングを停止
|
|
607
|
+
this.stopLogStream(sessionId);
|
|
608
|
+
};
|
|
609
|
+
// 一度だけ実行されるようにする
|
|
610
|
+
// Note: IPCServerBase doesn't extend EventEmitter, so we can't use EventCleanupHelper for it
|
|
611
|
+
// This is acceptable as IPCServerBase has its own cleanup mechanisms
|
|
612
|
+
this.ipcServer?.once('disconnect', disconnectHandler);
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Cleanup all streaming sessions
|
|
616
|
+
*/
|
|
617
|
+
cleanupAllStreamingSessions() {
|
|
618
|
+
for (const [, sessionInfo] of this.streamingSessions) {
|
|
619
|
+
sessionInfo.cleanup();
|
|
620
|
+
}
|
|
621
|
+
this.streamingSessions.clear();
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Clean up all managed listeners and components
|
|
625
|
+
*/
|
|
626
|
+
async cleanup() {
|
|
627
|
+
// Clean up streaming sessions first
|
|
628
|
+
this.cleanupAllStreamingSessions();
|
|
629
|
+
// Clean up listeners
|
|
630
|
+
await this.cleanupListeners();
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Clean up only listeners (without streaming sessions)
|
|
634
|
+
*/
|
|
635
|
+
async cleanupListeners() {
|
|
636
|
+
// Clean up all tracked listeners
|
|
637
|
+
await this.listenerCleanup.dispose();
|
|
638
|
+
// Clean up our own listeners
|
|
639
|
+
this.removeAllListeners();
|
|
640
|
+
// Listeners cleaned up by EventCleanupHelper
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Get statistics about listener management
|
|
644
|
+
*/
|
|
645
|
+
getListenerStats() {
|
|
646
|
+
const ownEvents = this.eventNames();
|
|
647
|
+
let ownListenersCount = 0;
|
|
648
|
+
for (const event of ownEvents) {
|
|
649
|
+
ownListenersCount += this.listenerCount(event);
|
|
650
|
+
}
|
|
651
|
+
return {
|
|
652
|
+
managedListeners: this.listenerCleanup.getListenerCount(),
|
|
653
|
+
ownListeners: ownListenersCount,
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Register a component with proper interface
|
|
658
|
+
*/
|
|
659
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
660
|
+
async registerComponent(name, instance) {
|
|
661
|
+
const startTime = Date.now();
|
|
662
|
+
console.log(`Registering component: ${name}`);
|
|
663
|
+
const component = {
|
|
664
|
+
name,
|
|
665
|
+
initialize: async () => {
|
|
666
|
+
console.log(`Initializing component: ${name}`);
|
|
667
|
+
if (instance == null) {
|
|
668
|
+
throw new Error(`Component ${name} instance is null or undefined`);
|
|
669
|
+
}
|
|
670
|
+
// Handle component-specific initialization methods
|
|
671
|
+
let startMethod = null;
|
|
672
|
+
if (name === 'processManager' &&
|
|
673
|
+
instance.startMonitoring &&
|
|
674
|
+
typeof instance.startMonitoring === 'function') {
|
|
675
|
+
startMethod = instance.startMonitoring.bind(instance);
|
|
676
|
+
}
|
|
677
|
+
else if (instance.start && typeof instance.start === 'function') {
|
|
678
|
+
startMethod = instance.start.bind(instance);
|
|
679
|
+
}
|
|
680
|
+
if (startMethod) {
|
|
681
|
+
const initStartTime = Date.now();
|
|
682
|
+
// Add timeout for component initialization
|
|
683
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
684
|
+
setTimeout(() => {
|
|
685
|
+
reject(new Error(`Component ${name} initialization timed out after 30 seconds`));
|
|
686
|
+
}, 30000); // 30 second timeout
|
|
687
|
+
});
|
|
688
|
+
try {
|
|
689
|
+
// Handle both async and sync start methods
|
|
690
|
+
const startPromise = Promise.resolve(startMethod());
|
|
691
|
+
await Promise.race([startPromise, timeoutPromise]);
|
|
692
|
+
const initTime = Date.now() - initStartTime;
|
|
693
|
+
console.log(`Component ${name} initialization completed in ${initTime}ms`);
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
console.error(`Component ${name} initialization failed:`, error);
|
|
697
|
+
throw error;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
console.log(`Component ${name} has no start() method - assuming ready`);
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
cleanup: async () => {
|
|
705
|
+
console.log(`Cleaning up component: ${name}`);
|
|
706
|
+
if (instance.stop && typeof instance.stop === 'function') {
|
|
707
|
+
await instance.stop();
|
|
708
|
+
}
|
|
709
|
+
else if (instance.cleanup && typeof instance.cleanup === 'function') {
|
|
710
|
+
await instance.cleanup();
|
|
711
|
+
}
|
|
712
|
+
console.log(`Component ${name} cleanup completed`);
|
|
713
|
+
},
|
|
714
|
+
isInitialized: () => {
|
|
715
|
+
if (instance.isRunning && typeof instance.isRunning === 'function') {
|
|
716
|
+
return instance.isRunning();
|
|
717
|
+
}
|
|
718
|
+
return true; // Assume initialized if no status method
|
|
719
|
+
},
|
|
720
|
+
};
|
|
721
|
+
this.components.set(name, component);
|
|
722
|
+
this.initializationOrder.push(name);
|
|
723
|
+
this.cleanupOrder.push(name);
|
|
724
|
+
await component.initialize();
|
|
725
|
+
const totalTime = Date.now() - startTime;
|
|
726
|
+
console.log(`Component ${name} registered and initialized in ${totalTime}ms`);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Rollback partial initialization
|
|
730
|
+
*/
|
|
731
|
+
async rollbackInitialization() {
|
|
732
|
+
const componentsToRollback = [...this.initializationOrder].reverse();
|
|
733
|
+
for (const componentName of componentsToRollback) {
|
|
734
|
+
try {
|
|
735
|
+
const component = this.components.get(componentName);
|
|
736
|
+
if (component) {
|
|
737
|
+
await component.cleanup();
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
catch {
|
|
741
|
+
// Ignore rollback errors
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
this.clearComponents();
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Clear all component references
|
|
748
|
+
*/
|
|
749
|
+
clearComponents() {
|
|
750
|
+
this.components.clear();
|
|
751
|
+
this.initializationOrder = [];
|
|
752
|
+
this.cleanupOrder = [];
|
|
753
|
+
this.configLoader = undefined;
|
|
754
|
+
this.processManager = undefined;
|
|
755
|
+
this.logManager = undefined;
|
|
756
|
+
this.ipcServer = undefined;
|
|
757
|
+
this.commandHandler = undefined;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Convert AppConfig to ProcessConfig format
|
|
761
|
+
*/
|
|
762
|
+
convertAppConfigToProcessConfig(
|
|
763
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
764
|
+
appConfig, appName
|
|
765
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
766
|
+
) {
|
|
767
|
+
return {
|
|
768
|
+
name: appName,
|
|
769
|
+
script: appConfig.script || appConfig.exec || 'node',
|
|
770
|
+
namespace: appConfig.namespace || 'default',
|
|
771
|
+
args: appConfig.args || [],
|
|
772
|
+
cwd: appConfig.cwd || process.cwd(),
|
|
773
|
+
env: { ...process.env, ...appConfig.env },
|
|
774
|
+
instances: appConfig.instances || 1,
|
|
775
|
+
autorestart: appConfig.autorestart ?? true,
|
|
776
|
+
watch: appConfig.watch ?? false,
|
|
777
|
+
max_memory_restart: appConfig.max_memory_restart || undefined,
|
|
778
|
+
max_restarts: appConfig.max_restarts || 15,
|
|
779
|
+
min_uptime: appConfig.min_uptime || 1000,
|
|
780
|
+
restart_delay: appConfig.restart_delay || 0,
|
|
781
|
+
note: appConfig.note || undefined,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Override EventEmitter methods for type safety
|
|
786
|
+
*/
|
|
787
|
+
emit(event, ...args) {
|
|
788
|
+
return super.emit(event, ...args);
|
|
789
|
+
}
|
|
790
|
+
on(event, listener) {
|
|
791
|
+
return super.on(event, listener);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
//# sourceMappingURL=component-manager.js.map
|