@yolo-croket-dev/core 1.7.44-slowquery.5 → 1.7.44-slowquery.7

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;
@@ -46,7 +56,71 @@ class ContextPromisePatch {
46
56
  if (abortSignal.aborted) {
47
57
  return Promise.reject(new Error(`REQUEST_ABORTED: Promise가 중단되었습니다 (${contextId})`));
48
58
  }
49
- const promise = Reflect.construct(target, args);
59
+ // Promise 생성
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ let promise;
62
+ // executor 함수를 래핑하여 abort 체크 추가
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ const originalExecutor = args[0];
65
+ if (originalExecutor) {
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ const wrappedExecutor = (resolve, reject) => {
68
+ // abort 체크 함수
69
+ const checkAbort = () => {
70
+ if (abortSignal.aborted) {
71
+ reject(new Error(`REQUEST_ABORTED: Promise가 중단되었습니다 (${contextId})`));
72
+ }
73
+ };
74
+ // abort 이벤트 리스너 등록
75
+ abortSignal.addEventListener('abort', checkAbort, { once: false });
76
+ // 원본 executor 호출
77
+ try {
78
+ originalExecutor(
79
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
80
+ (value) => {
81
+ abortSignal.removeEventListener('abort', checkAbort);
82
+ resolve(value);
83
+ },
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ (reason) => {
86
+ abortSignal.removeEventListener('abort', checkAbort);
87
+ reject(reason);
88
+ });
89
+ }
90
+ catch (error) {
91
+ abortSignal.removeEventListener('abort', checkAbort);
92
+ reject(error);
93
+ }
94
+ };
95
+ // 새로운 args 배열 생성
96
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
+ const newArgs = [
98
+ wrappedExecutor,
99
+ ...args.slice(1),
100
+ ];
101
+ promise = Reflect.construct(target, newArgs);
102
+ }
103
+ else {
104
+ promise = Reflect.construct(target, args);
105
+ }
106
+ // Promise 추적 추가
107
+ if (!ContextPromisePatch.contextPromises.has(contextId)) {
108
+ ContextPromisePatch.contextPromises.set(contextId, new Set());
109
+ }
110
+ ContextPromisePatch.contextPromises.get(contextId).add(promise);
111
+ // abort 이벤트 리스너 등록 (Promise가 abort되면 추적에서 제거하도록)
112
+ const abortListener = () => {
113
+ var _a;
114
+ // Promise가 abort되었을 때 추적에서 제거
115
+ (_a = ContextPromisePatch.contextPromises.get(contextId)) === null || _a === void 0 ? void 0 : _a.delete(promise);
116
+ };
117
+ abortSignal.addEventListener('abort', abortListener, { once: true });
118
+ // Promise 완료 시 추적에서 제거 및 리스너 해제
119
+ promise.finally(() => {
120
+ var _a;
121
+ (_a = ContextPromisePatch.contextPromises.get(contextId)) === null || _a === void 0 ? void 0 : _a.delete(promise);
122
+ abortSignal.removeEventListener('abort', abortListener);
123
+ });
50
124
  // Promise 체인에 자동으로 중단 확인 추가
51
125
  return promise.then((result) => {
52
126
  // 컨텍스트가 여전히 유효한지 확인
@@ -289,3 +363,6 @@ ContextPromisePatch.contextTimers = new Map();
289
363
  // timerId -> contextId 매핑
290
364
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
291
365
  ContextPromisePatch.timerContextMap = new Map();
366
+ // 컨텍스트별 활성 Promise 추적
367
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
368
+ 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
- // disable을 충분히 지연시켜서 모든 이벤트 리스너가 완료될 때까지 기다림
364
- setTimeout(() => {
365
- functions_1.AbortContext.disable();
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolo-croket-dev/core",
3
- "version": "1.7.44-slowquery.5",
3
+ "version": "1.7.44-slowquery.7",
4
4
  "author": "Yolo Co., Ltd.",
5
5
  "description": "Yolo commonization module",
6
6
  "main": "index.js",