@yolo-croket-dev/core 1.7.43 → 1.7.44-slowquery.1
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.
|
@@ -16,6 +16,7 @@ export declare class AbortContext {
|
|
|
16
16
|
requestId: string;
|
|
17
17
|
} | null;
|
|
18
18
|
static disable(): void;
|
|
19
|
+
static disableDeferred(): void;
|
|
19
20
|
static endContext(context?: RequestContext): void;
|
|
20
21
|
static updateContext(updatedData: Partial<RequestContext>): void;
|
|
21
22
|
/**
|
|
@@ -35,6 +35,11 @@ class AbortContext {
|
|
|
35
35
|
static disable() {
|
|
36
36
|
this.asyncLocalStorage.disable();
|
|
37
37
|
}
|
|
38
|
+
static disableDeferred() {
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
this.asyncLocalStorage.disable();
|
|
41
|
+
}, 0);
|
|
42
|
+
}
|
|
38
43
|
// 컨텍스트 종료
|
|
39
44
|
// eslint-disable-next-line consistent-return
|
|
40
45
|
static endContext(context) {
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export declare class ContextPromisePatch {
|
|
2
2
|
private static isPatched;
|
|
3
3
|
private static originalPromise;
|
|
4
|
+
private static originalSetTimeout;
|
|
5
|
+
private static originalSetInterval;
|
|
6
|
+
private static originalClearTimeout;
|
|
7
|
+
private static originalClearInterval;
|
|
4
8
|
static patch(): void;
|
|
5
9
|
private static patchPromise;
|
|
10
|
+
private static patchTimeouts;
|
|
6
11
|
static unpatch(): void;
|
|
7
12
|
}
|
|
@@ -8,7 +8,12 @@ class ContextPromisePatch {
|
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
this.originalPromise = global.Promise;
|
|
11
|
+
this.originalSetTimeout = global.setTimeout;
|
|
12
|
+
this.originalSetInterval = global.setInterval;
|
|
13
|
+
this.originalClearTimeout = global.clearTimeout;
|
|
14
|
+
this.originalClearInterval = global.clearInterval;
|
|
11
15
|
this.patchPromise();
|
|
16
|
+
this.patchTimeouts();
|
|
12
17
|
this.isPatched = true;
|
|
13
18
|
}
|
|
14
19
|
static patchPromise() {
|
|
@@ -103,11 +108,126 @@ class ContextPromisePatch {
|
|
|
103
108
|
return originalReject.call(global.Promise, reason);
|
|
104
109
|
};
|
|
105
110
|
}
|
|
111
|
+
static patchTimeouts() {
|
|
112
|
+
// 각 컨텍스트별로 활성 타이머를 추적
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
|
+
const activeTimers = new Map();
|
|
115
|
+
// setTimeout 패치
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
+
global.setTimeout = (handler, timeout,
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
+
...args
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
121
|
+
) => {
|
|
122
|
+
const currentContext = abort_context_1.AbortContext.getCurrentContext();
|
|
123
|
+
if (!currentContext) {
|
|
124
|
+
// 원본 함수에 args 전달 (타입 안전하게)
|
|
125
|
+
if (args.length > 0) {
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
|
+
return this.originalSetTimeout(handler, timeout, ...args);
|
|
128
|
+
}
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
130
|
+
return this.originalSetTimeout(handler, timeout);
|
|
131
|
+
}
|
|
132
|
+
const abortSignal = currentContext.abortSignal;
|
|
133
|
+
const contextId = currentContext.requestId;
|
|
134
|
+
if (abortSignal.aborted) {
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
136
|
+
throw new Error(`REQUEST_ABORTED: setTimeout이 중단되었습니다 (${contextId})`);
|
|
137
|
+
}
|
|
138
|
+
const originalHandler = typeof handler === 'function' ? handler : undefined;
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
140
|
+
const wrappedHandler = () => {
|
|
141
|
+
// 타이머 실행 시점에 abort 여부 확인
|
|
142
|
+
if (abortSignal.aborted) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (originalHandler) {
|
|
146
|
+
originalHandler();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
+
const timeoutId = this.originalSetTimeout(wrappedHandler, timeout);
|
|
151
|
+
activeTimers.set(timeoutId, {
|
|
152
|
+
contextId,
|
|
153
|
+
abortSignal,
|
|
154
|
+
});
|
|
155
|
+
const onAbort = () => {
|
|
156
|
+
this.originalClearTimeout(timeoutId);
|
|
157
|
+
activeTimers.delete(timeoutId);
|
|
158
|
+
};
|
|
159
|
+
abortSignal.addEventListener('abort', onAbort, { once: true });
|
|
160
|
+
return timeoutId;
|
|
161
|
+
};
|
|
162
|
+
// setInterval 패치
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
164
|
+
global.setInterval = (handler, timeout,
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
166
|
+
...args
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
168
|
+
) => {
|
|
169
|
+
const currentContext = abort_context_1.AbortContext.getCurrentContext();
|
|
170
|
+
if (!currentContext) {
|
|
171
|
+
// 원본 함수에 args 전달 (타입 안전하게)
|
|
172
|
+
if (args.length > 0) {
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
|
+
return this.originalSetInterval(handler, timeout, ...args);
|
|
175
|
+
}
|
|
176
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
177
|
+
return this.originalSetInterval(handler, timeout);
|
|
178
|
+
}
|
|
179
|
+
const abortSignal = currentContext.abortSignal;
|
|
180
|
+
const contextId = currentContext.requestId;
|
|
181
|
+
if (abortSignal.aborted) {
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
183
|
+
throw new Error(`REQUEST_ABORTED: setInterval이 중단되었습니다 (${contextId})`);
|
|
184
|
+
}
|
|
185
|
+
const originalHandler = typeof handler === 'function' ? handler : undefined;
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
187
|
+
const wrappedHandler = () => {
|
|
188
|
+
// 타이머 실행 시점에 abort 여부 확인
|
|
189
|
+
if (abortSignal.aborted) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (originalHandler) {
|
|
193
|
+
originalHandler();
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
197
|
+
const intervalId = this.originalSetInterval(wrappedHandler, timeout);
|
|
198
|
+
activeTimers.set(intervalId, {
|
|
199
|
+
contextId,
|
|
200
|
+
abortSignal,
|
|
201
|
+
});
|
|
202
|
+
const onAbort = () => {
|
|
203
|
+
this.originalClearInterval(intervalId);
|
|
204
|
+
activeTimers.delete(intervalId);
|
|
205
|
+
};
|
|
206
|
+
abortSignal.addEventListener('abort', onAbort, { once: true });
|
|
207
|
+
return intervalId;
|
|
208
|
+
};
|
|
209
|
+
// clearTimeout 패치
|
|
210
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
211
|
+
global.clearTimeout = (timerId) => {
|
|
212
|
+
activeTimers.delete(timerId);
|
|
213
|
+
this.originalClearTimeout(timerId);
|
|
214
|
+
};
|
|
215
|
+
// clearInterval 패치
|
|
216
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
|
+
global.clearInterval = (timerId) => {
|
|
218
|
+
activeTimers.delete(timerId);
|
|
219
|
+
this.originalClearInterval(timerId);
|
|
220
|
+
};
|
|
221
|
+
}
|
|
106
222
|
static unpatch() {
|
|
107
223
|
if (!this.isPatched) {
|
|
108
224
|
return;
|
|
109
225
|
}
|
|
110
226
|
global.Promise = this.originalPromise;
|
|
227
|
+
global.setTimeout = this.originalSetTimeout;
|
|
228
|
+
global.setInterval = this.originalSetInterval;
|
|
229
|
+
global.clearTimeout = this.originalClearTimeout;
|
|
230
|
+
global.clearInterval = this.originalClearInterval;
|
|
111
231
|
this.isPatched = false;
|
|
112
232
|
}
|
|
113
233
|
}
|
|
@@ -57,6 +57,7 @@ let RPCInterceptor = class RPCInterceptor {
|
|
|
57
57
|
this.gracefulShutdownService = gracefulShutdownService;
|
|
58
58
|
this.DEFAULT_TIMEOUT = 1000 * 60 * 29; // 29분 타임아웃
|
|
59
59
|
this.DEFAULT_TIMEOUT_MESSAGE = '요청이 타임아웃되었습니다.';
|
|
60
|
+
context_promise_patch_1.ContextPromisePatch.patch();
|
|
60
61
|
}
|
|
61
62
|
maxLengthOverShorten(data) {
|
|
62
63
|
if (typeof data !== 'string') {
|
|
@@ -169,7 +170,6 @@ let RPCInterceptor = class RPCInterceptor {
|
|
|
169
170
|
correlationId,
|
|
170
171
|
isMessageAck: false,
|
|
171
172
|
};
|
|
172
|
-
context_promise_patch_1.ContextPromisePatch.patch();
|
|
173
173
|
let abortController = new AbortController();
|
|
174
174
|
/** consume 메시지 전부 cancel */
|
|
175
175
|
if (this.gracefulShutdownService.isApplicationExit) {
|
|
@@ -357,7 +357,7 @@ let RPCInterceptor = class RPCInterceptor {
|
|
|
357
357
|
error: localErrorProcessor,
|
|
358
358
|
}), (0, operators_1.finalize)(() => {
|
|
359
359
|
this.gracefulShutdownService.popActiveInterceptors(execInterceptor);
|
|
360
|
-
functions_1.AbortContext.
|
|
360
|
+
functions_1.AbortContext.disableDeferred();
|
|
361
361
|
abortController = null;
|
|
362
362
|
return rxjs_1.EMPTY;
|
|
363
363
|
})));
|