@fuzionx/core 0.1.38 → 0.1.39
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/lib/app.js +9 -5
- package/lib/context.js +5 -1
- package/lib/middleware.js +8 -2
- package/package.json +2 -2
- package/types/index.d.ts +2 -2
package/lib/app.js
CHANGED
|
@@ -214,7 +214,8 @@ export class FuzionXApp {
|
|
|
214
214
|
for (const id in cluster.workers) {
|
|
215
215
|
cluster.workers[id].process.kill('SIGTERM');
|
|
216
216
|
}
|
|
217
|
-
|
|
217
|
+
const shutdownTimeout = this._appConfig?.shutdown_timeout || 5000;
|
|
218
|
+
setTimeout(() => process.exit(0), shutdownTimeout);
|
|
218
219
|
};
|
|
219
220
|
process.once('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
|
220
221
|
process.once('SIGINT', () => gracefulShutdown('SIGINT'));
|
|
@@ -227,7 +228,7 @@ export class FuzionXApp {
|
|
|
227
228
|
}
|
|
228
229
|
});
|
|
229
230
|
|
|
230
|
-
if (callback)
|
|
231
|
+
if (callback) setImmediate(() => callback());
|
|
231
232
|
return this;
|
|
232
233
|
}
|
|
233
234
|
|
|
@@ -252,7 +253,8 @@ export class FuzionXApp {
|
|
|
252
253
|
shutdownCalled = true;
|
|
253
254
|
console.log(`[fuzionx] ${signal} received — graceful shutdown (PID=${process.pid})`);
|
|
254
255
|
this._bridge.stopFusionServer();
|
|
255
|
-
|
|
256
|
+
const shutdownTimeout = this._appConfig?.shutdown_timeout || 5000;
|
|
257
|
+
setTimeout(() => process.exit(0), shutdownTimeout);
|
|
256
258
|
};
|
|
257
259
|
process.once('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
|
258
260
|
process.once('SIGINT', () => gracefulShutdown('SIGINT'));
|
|
@@ -272,13 +274,15 @@ export class FuzionXApp {
|
|
|
272
274
|
|
|
273
275
|
// ── Error Recovery ──
|
|
274
276
|
process.on('uncaughtException', (err) => {
|
|
275
|
-
console.error('[fuzionx] uncaughtException:', err.message);
|
|
277
|
+
console.error('[fuzionx] uncaughtException:', err.message, err.stack);
|
|
278
|
+
// 불안정 상태 방지: 짧은 유예 후 프로세스 종료
|
|
279
|
+
setTimeout(() => process.exit(1), 1000);
|
|
276
280
|
});
|
|
277
281
|
process.on('unhandledRejection', (reason) => {
|
|
278
282
|
console.error('[fuzionx] unhandledRejection:', reason);
|
|
279
283
|
});
|
|
280
284
|
|
|
281
|
-
if (callback)
|
|
285
|
+
if (callback) setImmediate(() => callback());
|
|
282
286
|
return this;
|
|
283
287
|
}
|
|
284
288
|
|
package/lib/context.js
CHANGED
|
@@ -176,8 +176,12 @@ const ResProto = {
|
|
|
176
176
|
this._headers[key] = value;
|
|
177
177
|
return this;
|
|
178
178
|
},
|
|
179
|
-
/** Fusion 응답 포맷으로 변환 — 공유
|
|
179
|
+
/** Fusion 응답 포맷으로 변환 — sync: 공유 객체, async: 새 객체 */
|
|
180
180
|
_toFusionResponse() {
|
|
181
|
+
// async (비공유) 인스턴스면 새 객체 반환 → race condition 방지
|
|
182
|
+
if (this !== _sharedRes) {
|
|
183
|
+
return { status: this._statusCode, body: this._body, headers: this._headers };
|
|
184
|
+
}
|
|
181
185
|
_sharedResponse.status = this._statusCode;
|
|
182
186
|
_sharedResponse.body = this._body;
|
|
183
187
|
_sharedResponse.headers = this._headers;
|
package/lib/middleware.js
CHANGED
|
@@ -23,8 +23,14 @@ export function runMiddlewareChain(handlers, req, res) {
|
|
|
23
23
|
const handler = handlers[index++];
|
|
24
24
|
const result = handler(req, res, next);
|
|
25
25
|
|
|
26
|
-
// 핸들러가 Promise를 리턴하면 (async 함수) → 전파
|
|
27
|
-
//
|
|
26
|
+
// 핸들러가 Promise를 리턴하면 (async 함수) → 체인 완료까지 전파
|
|
27
|
+
// async 핸들러 내부에서 await next()를 호출하므로 후속 체인은 Promise 안에서 실행됨
|
|
28
|
+
if (result && typeof result.then === 'function') {
|
|
29
|
+
return result.catch((e) => {
|
|
30
|
+
// async 핸들러의 unhandled rejection 방지
|
|
31
|
+
if (!res._sent) throw e;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
28
34
|
return result;
|
|
29
35
|
}
|
|
30
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzionx/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Express-style Node.js framework powered by FuzionX native bridge — 167K RPS single process",
|
|
6
6
|
"main": "index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"url": "https://github.com/saytohenry/fuzionx"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@fuzionx/bridge": "^0.1.
|
|
21
|
+
"@fuzionx/bridge": "^0.1.39"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"index.js",
|
package/types/index.d.ts
CHANGED
|
@@ -78,8 +78,8 @@ export interface CryptoHelper {
|
|
|
78
78
|
uuid(): string;
|
|
79
79
|
md5(input: string): string;
|
|
80
80
|
sha256(input: string): string;
|
|
81
|
-
encrypt(
|
|
82
|
-
decrypt(
|
|
81
|
+
encrypt(key: string, plaintext: string): string;
|
|
82
|
+
decrypt(key: string, ciphertext: string): string;
|
|
83
83
|
encryptCustom(plaintext: string, key: string): string;
|
|
84
84
|
decryptCustom(ciphertext: string, key: string): string;
|
|
85
85
|
getUaSlice(userAgent: string): string;
|