@yolo-croket-dev/core 1.7.44-slowquery.5 → 1.7.44-slowquery.6
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.
|
@@ -7,10 +7,15 @@ export declare class ContextPromisePatch {
|
|
|
7
7
|
private static originalClearInterval;
|
|
8
8
|
private static contextTimers;
|
|
9
9
|
private static timerContextMap;
|
|
10
|
+
private static contextPromises;
|
|
10
11
|
/**
|
|
11
12
|
* 특정 컨텍스트의 모든 타이머 정리
|
|
12
13
|
*/
|
|
13
14
|
static clearContextTimers(contextId: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* 특정 컨텍스트의 모든 Promise가 완료될 때까지 대기
|
|
17
|
+
*/
|
|
18
|
+
static waitForContextPromises(contextId: string): Promise<void>;
|
|
14
19
|
static patch(): void;
|
|
15
20
|
private static patchPromise;
|
|
16
21
|
private static patchTimeouts;
|
|
@@ -17,6 +17,16 @@ class ContextPromisePatch {
|
|
|
17
17
|
this.contextTimers.delete(contextId);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* 특정 컨텍스트의 모든 Promise가 완료될 때까지 대기
|
|
22
|
+
*/
|
|
23
|
+
static async waitForContextPromises(contextId) {
|
|
24
|
+
const promises = this.contextPromises.get(contextId);
|
|
25
|
+
if (promises && promises.size > 0) {
|
|
26
|
+
// 모든 Promise가 완료될 때까지 기다림
|
|
27
|
+
await Promise.allSettled(Array.from(promises));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
static patch() {
|
|
21
31
|
if (this.isPatched) {
|
|
22
32
|
return;
|
|
@@ -47,8 +57,45 @@ class ContextPromisePatch {
|
|
|
47
57
|
return Promise.reject(new Error(`REQUEST_ABORTED: Promise가 중단되었습니다 (${contextId})`));
|
|
48
58
|
}
|
|
49
59
|
const promise = Reflect.construct(target, args);
|
|
60
|
+
// abort 이벤트 리스너 추가하여 Promise를 즉시 reject
|
|
61
|
+
const wrappedPromise = new Promise((resolve, reject) => {
|
|
62
|
+
const checkAbort = () => {
|
|
63
|
+
if (abortSignal.aborted) {
|
|
64
|
+
reject(new Error(`REQUEST_ABORTED: Promise가 중단되었습니다 (${contextId})`));
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
// abort 이벤트 리스너 등록
|
|
68
|
+
abortSignal.addEventListener('abort', checkAbort);
|
|
69
|
+
// 원본 promise가 완료될 때까지 기다림
|
|
70
|
+
promise
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
.then((result) => {
|
|
73
|
+
abortSignal.removeEventListener('abort', checkAbort);
|
|
74
|
+
resolve(result);
|
|
75
|
+
})
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
|
+
.catch((error) => {
|
|
78
|
+
abortSignal.removeEventListener('abort', checkAbort);
|
|
79
|
+
reject(error);
|
|
80
|
+
});
|
|
81
|
+
// 이미 abort된 경우
|
|
82
|
+
if (abortSignal.aborted) {
|
|
83
|
+
abortSignal.removeEventListener('abort', checkAbort);
|
|
84
|
+
reject(new Error(`REQUEST_ABORTED: Promise가 중단되었습니다 (${contextId})`));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
// Promise 추적 추가
|
|
88
|
+
if (!ContextPromisePatch.contextPromises.has(contextId)) {
|
|
89
|
+
ContextPromisePatch.contextPromises.set(contextId, new Set());
|
|
90
|
+
}
|
|
91
|
+
ContextPromisePatch.contextPromises.get(contextId).add(wrappedPromise);
|
|
92
|
+
// Promise 완료 시 추적에서 제거
|
|
93
|
+
wrappedPromise.finally(() => {
|
|
94
|
+
var _a;
|
|
95
|
+
(_a = ContextPromisePatch.contextPromises.get(contextId)) === null || _a === void 0 ? void 0 : _a.delete(wrappedPromise);
|
|
96
|
+
});
|
|
50
97
|
// Promise 체인에 자동으로 중단 확인 추가
|
|
51
|
-
return
|
|
98
|
+
return wrappedPromise.then((result) => {
|
|
52
99
|
// 컨텍스트가 여전히 유효한지 확인
|
|
53
100
|
const currentContextCheck = abort_context_1.AbortContext.getCurrentContext();
|
|
54
101
|
if (!currentContextCheck || currentContextCheck.requestId !== contextId) {
|
|
@@ -289,3 +336,6 @@ ContextPromisePatch.contextTimers = new Map();
|
|
|
289
336
|
// timerId -> contextId 매핑
|
|
290
337
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
291
338
|
ContextPromisePatch.timerContextMap = new Map();
|
|
339
|
+
// 컨텍스트별 활성 Promise 추적
|
|
340
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
341
|
+
ContextPromisePatch.contextPromises = new Map();
|
|
@@ -355,15 +355,14 @@ let RPCInterceptor = class RPCInterceptor {
|
|
|
355
355
|
}
|
|
356
356
|
},
|
|
357
357
|
error: localErrorProcessor,
|
|
358
|
-
}), (0, operators_1.finalize)(() => {
|
|
358
|
+
}), (0, operators_1.finalize)(async () => {
|
|
359
359
|
this.gracefulShutdownService.popActiveInterceptors(execInterceptor);
|
|
360
360
|
// 활성 타이머를 모두 정리
|
|
361
361
|
context_promise_patch_1.ContextPromisePatch.clearContextTimers(execInterceptor.traceId);
|
|
362
362
|
abortController = null;
|
|
363
|
-
//
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}, 100);
|
|
363
|
+
// 모든 Promise가 완료될 때까지 기다림
|
|
364
|
+
await context_promise_patch_1.ContextPromisePatch.waitForContextPromises(execInterceptor.traceId);
|
|
365
|
+
functions_1.AbortContext.disable();
|
|
367
366
|
return rxjs_1.EMPTY;
|
|
368
367
|
})));
|
|
369
368
|
}
|