@porulle/core 0.46.0 → 0.47.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/kernel/hooks/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKpF,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAKzE;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/kernel/hooks/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKpF,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAKzE;AA4FD,wBAAsB,cAAc,CAAC,CAAC,EACpC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EACtB,IAAI,EAAE,CAAC,EACP,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,EAC1D,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAClC,YAAY,EAAE,KAAK,GAAG,IAAI,EAC1B,eAAe,EAAE,OAAO,EACxB,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,iBAAiB,GAAE,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,OAAqB,GAC5E,OAAO,CAAC,UAAU,CAAC,CAwErB"}
|
|
@@ -31,6 +31,34 @@ function inTransactionHookContext(context) {
|
|
|
31
31
|
}
|
|
32
32
|
/** Default hook timeout: 20 seconds */
|
|
33
33
|
const HOOK_TIMEOUT_MS = 20_000;
|
|
34
|
+
/**
|
|
35
|
+
* Warn above this. The timeout is the wrong instrument for the common case: a hook does not have
|
|
36
|
+
* to reach 20 s to be a problem, and by the time it does the damage is already spent.
|
|
37
|
+
*
|
|
38
|
+
* An in-transaction hook holds a pooled Postgres transaction for its whole duration. An
|
|
39
|
+
* after-commit one extends the invocation that wrote — on Workers a promise the invocation does
|
|
40
|
+
* not outlive, so the writer waits for it. `failures.ts` records what that costs unobserved: four
|
|
41
|
+
* connector suites took 578.23 s instead of 27.29 s and logged 51 `deliverWebhooks timed out after
|
|
42
|
+
* 20000ms`, exit 0, 22 of 22 passing. The only thing that disagreed was the wall clock.
|
|
43
|
+
*
|
|
44
|
+
* 100 ms matches Vendure's blocking-handler warning, and the remedy is the same one it names:
|
|
45
|
+
* move non-trivial work to the job queue and let the hook enqueue it.
|
|
46
|
+
*/
|
|
47
|
+
const HOOK_SLOW_MS = 100;
|
|
48
|
+
function warnIfSlow(context, hookName, startedAt, inTransaction) {
|
|
49
|
+
const elapsed = Date.now() - startedAt;
|
|
50
|
+
if (elapsed <= HOOK_SLOW_MS)
|
|
51
|
+
return;
|
|
52
|
+
context.logger.warn(`After-hook "${hookName}" took ${elapsed}ms`, {
|
|
53
|
+
hookName,
|
|
54
|
+
elapsedMs: elapsed,
|
|
55
|
+
inTransaction,
|
|
56
|
+
requestId: context.requestId,
|
|
57
|
+
hint: inTransaction
|
|
58
|
+
? "Runs inside the writing transaction and holds its connection for this long. Enqueue the work instead."
|
|
59
|
+
: "Runs after commit but inside the same invocation, so the writer waits for it. Enqueue the work instead.",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
34
62
|
function withTimeout(promiseOrValue, timeoutMs, hookName) {
|
|
35
63
|
const promise = Promise.resolve(promiseOrValue);
|
|
36
64
|
return new Promise((resolve, reject) => {
|
|
@@ -85,8 +113,10 @@ export async function runAfterHooks(hooks, originalData, committedResult, operat
|
|
|
85
113
|
: { ...context, tx: null },
|
|
86
114
|
}), HOOK_TIMEOUT_MS, hookName);
|
|
87
115
|
if (runsInTransaction(hook)) {
|
|
116
|
+
const startedAt = Date.now();
|
|
88
117
|
try {
|
|
89
118
|
await runHook();
|
|
119
|
+
warnIfSlow(context, hookName, startedAt, true);
|
|
90
120
|
}
|
|
91
121
|
catch (error) {
|
|
92
122
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -99,8 +129,10 @@ export async function runAfterHooks(hooks, originalData, committedResult, operat
|
|
|
99
129
|
continue;
|
|
100
130
|
}
|
|
101
131
|
const deferred = deferAfterCommit(async () => {
|
|
132
|
+
const startedAt = Date.now();
|
|
102
133
|
try {
|
|
103
134
|
await runHook();
|
|
135
|
+
warnIfSlow(context, hookName, startedAt, false);
|
|
104
136
|
}
|
|
105
137
|
catch (error) {
|
|
106
138
|
// Reported rather than collected: this runs after the commit, so the HookReport below has
|
|
@@ -116,8 +148,10 @@ export async function runAfterHooks(hooks, originalData, committedResult, operat
|
|
|
116
148
|
}
|
|
117
149
|
});
|
|
118
150
|
if (!deferred) {
|
|
151
|
+
const startedAt = Date.now();
|
|
119
152
|
try {
|
|
120
153
|
await runHook();
|
|
154
|
+
warnIfSlow(context, hookName, startedAt, false);
|
|
121
155
|
}
|
|
122
156
|
catch (error) {
|
|
123
157
|
const message = error instanceof Error ? error.message : String(error);
|
package/package.json
CHANGED
|
@@ -46,6 +46,38 @@ function inTransactionHookContext(context: HookContext): HookContext {
|
|
|
46
46
|
/** Default hook timeout: 20 seconds */
|
|
47
47
|
const HOOK_TIMEOUT_MS = 20_000;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Warn above this. The timeout is the wrong instrument for the common case: a hook does not have
|
|
51
|
+
* to reach 20 s to be a problem, and by the time it does the damage is already spent.
|
|
52
|
+
*
|
|
53
|
+
* An in-transaction hook holds a pooled Postgres transaction for its whole duration. An
|
|
54
|
+
* after-commit one extends the invocation that wrote — on Workers a promise the invocation does
|
|
55
|
+
* not outlive, so the writer waits for it. `failures.ts` records what that costs unobserved: four
|
|
56
|
+
* connector suites took 578.23 s instead of 27.29 s and logged 51 `deliverWebhooks timed out after
|
|
57
|
+
* 20000ms`, exit 0, 22 of 22 passing. The only thing that disagreed was the wall clock.
|
|
58
|
+
*
|
|
59
|
+
* 100 ms matches Vendure's blocking-handler warning, and the remedy is the same one it names:
|
|
60
|
+
* move non-trivial work to the job queue and let the hook enqueue it.
|
|
61
|
+
*/
|
|
62
|
+
const HOOK_SLOW_MS = 100;
|
|
63
|
+
|
|
64
|
+
function warnIfSlow(context: HookContext, hookName: string, startedAt: number, inTransaction: boolean): void {
|
|
65
|
+
const elapsed = Date.now() - startedAt;
|
|
66
|
+
if (elapsed <= HOOK_SLOW_MS) return;
|
|
67
|
+
context.logger.warn(
|
|
68
|
+
`After-hook "${hookName}" took ${elapsed}ms`,
|
|
69
|
+
{
|
|
70
|
+
hookName,
|
|
71
|
+
elapsedMs: elapsed,
|
|
72
|
+
inTransaction,
|
|
73
|
+
requestId: context.requestId,
|
|
74
|
+
hint: inTransaction
|
|
75
|
+
? "Runs inside the writing transaction and holds its connection for this long. Enqueue the work instead."
|
|
76
|
+
: "Runs after commit but inside the same invocation, so the writer waits for it. Enqueue the work instead.",
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
49
81
|
function withTimeout<T>(promiseOrValue: Promise<T> | T, timeoutMs: number, hookName: string): Promise<T> {
|
|
50
82
|
const promise = Promise.resolve(promiseOrValue);
|
|
51
83
|
return new Promise<T>((resolve, reject) => {
|
|
@@ -130,8 +162,10 @@ export async function runAfterHooks<TResult, TData = TResult>(
|
|
|
130
162
|
);
|
|
131
163
|
|
|
132
164
|
if (runsInTransaction(hook)) {
|
|
165
|
+
const startedAt = Date.now();
|
|
133
166
|
try {
|
|
134
167
|
await runHook();
|
|
168
|
+
warnIfSlow(context, hookName, startedAt, true);
|
|
135
169
|
} catch (error) {
|
|
136
170
|
const message = error instanceof Error ? error.message : String(error);
|
|
137
171
|
errors.push({ hookName, message });
|
|
@@ -144,8 +178,10 @@ export async function runAfterHooks<TResult, TData = TResult>(
|
|
|
144
178
|
}
|
|
145
179
|
|
|
146
180
|
const deferred = deferAfterCommit(async () => {
|
|
181
|
+
const startedAt = Date.now();
|
|
147
182
|
try {
|
|
148
183
|
await runHook();
|
|
184
|
+
warnIfSlow(context, hookName, startedAt, false);
|
|
149
185
|
} catch (error) {
|
|
150
186
|
// Reported rather than collected: this runs after the commit, so the HookReport below has
|
|
151
187
|
// already been returned to the caller and there is nowhere else for this failure to go.
|
|
@@ -161,8 +197,10 @@ export async function runAfterHooks<TResult, TData = TResult>(
|
|
|
161
197
|
});
|
|
162
198
|
|
|
163
199
|
if (!deferred) {
|
|
200
|
+
const startedAt = Date.now();
|
|
164
201
|
try {
|
|
165
202
|
await runHook();
|
|
203
|
+
warnIfSlow(context, hookName, startedAt, false);
|
|
166
204
|
} catch (error) {
|
|
167
205
|
const message = error instanceof Error ? error.message : String(error);
|
|
168
206
|
errors.push({ hookName, message });
|