react-on-rails-pro-node-renderer 16.4.0-rc.8 → 16.4.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.
- package/lib/shared/configBuilder.d.ts +1 -0
- package/lib/shared/configBuilder.d.ts.map +1 -1
- package/lib/shared/configBuilder.js +2 -0
- package/lib/shared/configBuilder.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/worker.d.ts.map +1 -1
- package/lib/worker.js +7 -3
- package/lib/worker.js.map +1 -1
- package/package.json +2 -2
- package/src/shared/configBuilder.ts +7 -0
- package/src/worker.ts +7 -3
- package/tests/configBuilder.test.ts +54 -0
- package/tests/uploadRaceCondition.test.ts +256 -2
package/lib/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAAe,MAAM,EAAa,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,mBAAmB,CAAC;AAKvF,OAAO,EAOL,KAAK,EAIN,MAAM,mBAAmB,CAAC;AAW3B,OAAO,QAAQ,oBAAoB,CAAC;IAClC,UAAU,aAAa;QAErB,KAAK,EAAE,KAAK,CAAC;KACd;CACF;AAED,OAAO,QAAQ,SAAS,CAAC;IAEvB,UAAU,cAAc;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB;CACF;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;AAInE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,qBAAqB,QAErE;AAiCD,eAAO,MAAM,YAAY,YAExB,CAAC;AAkBF,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAAe,MAAM,EAAa,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,mBAAmB,CAAC;AAKvF,OAAO,EAOL,KAAK,EAIN,MAAM,mBAAmB,CAAC;AAW3B,OAAO,QAAQ,oBAAoB,CAAC;IAClC,UAAU,aAAa;QAErB,KAAK,EAAE,KAAK,CAAC;KACd;CACF;AAED,OAAO,QAAQ,SAAS,CAAC;IAEvB,UAAU,cAAc;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB;CACF;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;AAInE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,qBAAqB,QAErE;AAiCD,eAAO,MAAM,YAAY,YAExB,CAAC;AAkBF,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;;EAqWlD"}
|
package/lib/worker.js
CHANGED
|
@@ -116,7 +116,7 @@ function run(config) {
|
|
|
116
116
|
// Store config in app state. From now it can be loaded by any module using
|
|
117
117
|
// getConfig():
|
|
118
118
|
(0, configBuilder_js_1.buildConfig)(config);
|
|
119
|
-
const { serverBundleCachePath, logHttpLevel, port, fastifyServerOptions, workersCount } = (0, configBuilder_js_1.getConfig)();
|
|
119
|
+
const { serverBundleCachePath, logHttpLevel, port, host, fastifyServerOptions, workersCount } = (0, configBuilder_js_1.getConfig)();
|
|
120
120
|
const app = (0, fastify_1.default)({
|
|
121
121
|
http2: useHttp2,
|
|
122
122
|
bodyLimit: 104857600, // 100 MB
|
|
@@ -392,9 +392,13 @@ function run(config) {
|
|
|
392
392
|
// we are extracting worker from cluster to avoid false TS error
|
|
393
393
|
const { worker } = cluster_1.default;
|
|
394
394
|
if (workersCount === 0 || cluster_1.default.isWorker) {
|
|
395
|
-
app.listen({ port }, () => {
|
|
395
|
+
app.listen({ port, host }, (err, address) => {
|
|
396
|
+
if (err) {
|
|
397
|
+
log_js_1.default.error({ err, host, port }, 'Node renderer failed to start');
|
|
398
|
+
process.exit(1);
|
|
399
|
+
}
|
|
396
400
|
const workerName = worker ? `worker #${worker.id}` : 'master (single-process)';
|
|
397
|
-
log_js_1.default.info(
|
|
401
|
+
log_js_1.default.info({ workerName, address }, 'Node renderer listening');
|
|
398
402
|
});
|
|
399
403
|
}
|
|
400
404
|
fastifyConfigFunctions.forEach((configFunction) => {
|
package/lib/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-on-rails-pro-node-renderer",
|
|
3
|
-
"version": "16.4.0
|
|
3
|
+
"version": "16.4.0",
|
|
4
4
|
"protocolVersion": "2.0.0",
|
|
5
5
|
"description": "React on Rails Pro Node Renderer for server-side rendering",
|
|
6
6
|
"main": "lib/ReactOnRailsProNodeRenderer.js",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"sentry-testkit": "^5.0.6",
|
|
61
61
|
"touch": "^3.1.0",
|
|
62
62
|
"typescript": "^5.4.3",
|
|
63
|
-
"react-on-rails": "16.4.0
|
|
63
|
+
"react-on-rails": "16.4.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@honeybadger-io/js": ">=4.0.0",
|
|
@@ -27,6 +27,10 @@ export interface Config {
|
|
|
27
27
|
// https://devcenter.heroku.com/articles/dyno-startup-behavior#port-binding-of-web-dynos
|
|
28
28
|
// Similarly on ControlPlane: https://docs.controlplane.com/reference/workload/containers#port-variable
|
|
29
29
|
port: number;
|
|
30
|
+
// The host/IP address the renderer should bind to.
|
|
31
|
+
// Defaults to 'localhost' (127.0.0.1). Set to '0.0.0.0' for containerized environments
|
|
32
|
+
// where external health checks need to reach the server (e.g. Docker, ECS with ALB).
|
|
33
|
+
host: string;
|
|
30
34
|
// The renderer log level
|
|
31
35
|
logLevel: LevelWithSilent;
|
|
32
36
|
// The HTTP server log level
|
|
@@ -143,6 +147,8 @@ const defaultConfig: Config = {
|
|
|
143
147
|
// Use env port if we run on Heroku
|
|
144
148
|
port: Number(env.RENDERER_PORT) || DEFAULT_PORT,
|
|
145
149
|
|
|
150
|
+
host: env.RENDERER_HOST || 'localhost',
|
|
151
|
+
|
|
146
152
|
// Show only important messages by default
|
|
147
153
|
logLevel: logLevel(env.RENDERER_LOG_LEVEL || DEFAULT_LOG_LEVEL),
|
|
148
154
|
|
|
@@ -194,6 +200,7 @@ const defaultConfig: Config = {
|
|
|
194
200
|
function envValuesUsed() {
|
|
195
201
|
return {
|
|
196
202
|
RENDERER_PORT: !userConfig.port && env.RENDERER_PORT,
|
|
203
|
+
RENDERER_HOST: !('host' in userConfig) && env.RENDERER_HOST,
|
|
197
204
|
RENDERER_LOG_LEVEL: !userConfig.logLevel && env.RENDERER_LOG_LEVEL,
|
|
198
205
|
RENDERER_LOG_HTTP_LEVEL: !userConfig.logHttpLevel && env.RENDERER_LOG_HTTP_LEVEL,
|
|
199
206
|
RENDERER_SERVER_BUNDLE_CACHE_PATH:
|
package/src/worker.ts
CHANGED
|
@@ -125,7 +125,7 @@ export default function run(config: Partial<Config>) {
|
|
|
125
125
|
// getConfig():
|
|
126
126
|
buildConfig(config);
|
|
127
127
|
|
|
128
|
-
const { serverBundleCachePath, logHttpLevel, port, fastifyServerOptions, workersCount } = getConfig();
|
|
128
|
+
const { serverBundleCachePath, logHttpLevel, port, host, fastifyServerOptions, workersCount } = getConfig();
|
|
129
129
|
|
|
130
130
|
const app = fastify({
|
|
131
131
|
http2: useHttp2 as true,
|
|
@@ -462,9 +462,13 @@ export default function run(config: Partial<Config>) {
|
|
|
462
462
|
// we are extracting worker from cluster to avoid false TS error
|
|
463
463
|
const { worker } = cluster;
|
|
464
464
|
if (workersCount === 0 || cluster.isWorker) {
|
|
465
|
-
app.listen({ port }, () => {
|
|
465
|
+
app.listen({ port, host }, (err, address) => {
|
|
466
|
+
if (err) {
|
|
467
|
+
log.error({ err, host, port }, 'Node renderer failed to start');
|
|
468
|
+
process.exit(1);
|
|
469
|
+
}
|
|
466
470
|
const workerName = worker ? `worker #${worker.id}` : 'master (single-process)';
|
|
467
|
-
log.info(
|
|
471
|
+
log.info({ workerName, address }, 'Node renderer listening');
|
|
468
472
|
});
|
|
469
473
|
}
|
|
470
474
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
describe('configBuilder', () => {
|
|
2
|
+
const originalRendererHost = process.env.RENDERER_HOST;
|
|
3
|
+
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
if (originalRendererHost === undefined) {
|
|
6
|
+
delete process.env.RENDERER_HOST;
|
|
7
|
+
} else {
|
|
8
|
+
process.env.RENDERER_HOST = originalRendererHost;
|
|
9
|
+
}
|
|
10
|
+
jest.restoreAllMocks();
|
|
11
|
+
jest.resetModules();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function loadConfigBuilderWithMockedLogger() {
|
|
15
|
+
const info = jest.fn();
|
|
16
|
+
jest.doMock('../src/shared/log', () => ({
|
|
17
|
+
__esModule: true,
|
|
18
|
+
default: {
|
|
19
|
+
info,
|
|
20
|
+
error: jest.fn(),
|
|
21
|
+
warn: jest.fn(),
|
|
22
|
+
fatal: jest.fn(),
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
const { buildConfig, logSanitizedConfig } = jest.requireActual('../src/shared/configBuilder');
|
|
26
|
+
return { buildConfig, logSanitizedConfig, info };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function envValuesUsedForRenderedConfig(userConfig: { host?: string }) {
|
|
30
|
+
const { buildConfig, logSanitizedConfig, info } = loadConfigBuilderWithMockedLogger();
|
|
31
|
+
|
|
32
|
+
buildConfig(userConfig);
|
|
33
|
+
logSanitizedConfig();
|
|
34
|
+
|
|
35
|
+
const logPayload = info.mock.calls[0][0] as Record<string, unknown>;
|
|
36
|
+
return logPayload['ENV values used for settings (use "RENDERER_" prefix)'] as Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
it('marks RENDERER_HOST as env-provided when host is omitted from user config', () => {
|
|
40
|
+
process.env.RENDERER_HOST = '0.0.0.0';
|
|
41
|
+
|
|
42
|
+
const envValues = envValuesUsedForRenderedConfig({});
|
|
43
|
+
|
|
44
|
+
expect(envValues.RENDERER_HOST).toBe('0.0.0.0');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('does not mark RENDERER_HOST as env-provided when host key exists in user config', () => {
|
|
48
|
+
process.env.RENDERER_HOST = '0.0.0.0';
|
|
49
|
+
|
|
50
|
+
const envValues = envValuesUsedForRenderedConfig({ host: '' });
|
|
51
|
+
|
|
52
|
+
expect(envValues.RENDERER_HOST).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Strategy: a preHandler barrier guarantees both requests' onFile phases
|
|
11
11
|
* complete before either route handler runs, making the race deterministic.
|
|
12
|
+
*
|
|
13
|
+
* Concurrency evidence (issue #2472): instrumented lock/unlock wrappers record
|
|
14
|
+
* timestamped events to prove that same-bundle requests are serialized (lock
|
|
15
|
+
* regions do not overlap) while different-bundle requests run concurrently
|
|
16
|
+
* (lock regions DO overlap).
|
|
12
17
|
*/
|
|
13
18
|
import path from 'path';
|
|
14
19
|
import fs from 'fs';
|
|
@@ -29,6 +34,73 @@ const railsEnv = 'test';
|
|
|
29
34
|
|
|
30
35
|
disableHttp2();
|
|
31
36
|
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Event recorder for concurrency evidence (issue #2472)
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
type TimestampedEvent = { label: string; timestamp: number };
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Module-level event log shared between the mock factory and test assertions.
|
|
45
|
+
* Prefixed with "mock" so Jest's out-of-scope variable check allows access
|
|
46
|
+
* from inside jest.mock() factories.
|
|
47
|
+
*/
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
const mockEventLog: TimestampedEvent[] = ((global as any).__lockEventLog ??= []);
|
|
50
|
+
|
|
51
|
+
function clearEvents() {
|
|
52
|
+
mockEventLog.length = 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getEvents(prefix: string): TimestampedEvent[] {
|
|
56
|
+
return mockEventLog.filter((e) => e.label.startsWith(prefix));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Mock lock/unlock to record acquire/release events
|
|
61
|
+
//
|
|
62
|
+
// We use plain functions (not jest.fn()) so that resetMocks:true does NOT
|
|
63
|
+
// clear the implementation between tests. The real lock/unlock behaviour is
|
|
64
|
+
// always preserved; we just wrap it with event recording.
|
|
65
|
+
//
|
|
66
|
+
// Variables referenced inside jest.mock() factories must be prefixed with
|
|
67
|
+
// "mock" (Jest hoisting constraint). We use `mockEventLog` (stored on
|
|
68
|
+
// global) and inline `require('path')` to satisfy this rule.
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
jest.mock('../src/shared/locks', () => {
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, global-require
|
|
73
|
+
const mockPath = require('path');
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
75
|
+
const mockActualLocks = jest.requireActual('../src/shared/locks');
|
|
76
|
+
return {
|
|
77
|
+
__esModule: true,
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
lock: async (...args: any[]) => {
|
|
80
|
+
const filename = args[0] as string;
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
82
|
+
const result = await mockActualLocks.lock(...args);
|
|
83
|
+
// Record which bundle acquired the lock (use last path segment as key)
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
85
|
+
const bundleKey = mockPath.basename(mockPath.dirname(filename)) as string;
|
|
86
|
+
mockEventLog.push({ label: `${bundleKey}:lock-acquired`, timestamp: Date.now() });
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
88
|
+
return result;
|
|
89
|
+
},
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
91
|
+
unlock: async (...args: any[]) => {
|
|
92
|
+
const lockfileName = args[0] as string;
|
|
93
|
+
// Strip the .lock suffix, then get the bundle key
|
|
94
|
+
const withoutLock = lockfileName.replace(/\.lock$/, '');
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
96
|
+
const bundleKey = mockPath.basename(mockPath.dirname(withoutLock)) as string;
|
|
97
|
+
mockEventLog.push({ label: `${bundleKey}:lock-released`, timestamp: Date.now() });
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
99
|
+
await mockActualLocks.unlock(...args);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
|
|
32
104
|
/**
|
|
33
105
|
* Adds a preHandler barrier hook to the Fastify app that blocks until
|
|
34
106
|
* `expectedCount` requests have all reached the preHandler lifecycle stage.
|
|
@@ -70,6 +142,7 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
70
142
|
|
|
71
143
|
beforeEach(async () => {
|
|
72
144
|
await resetForTest(testName);
|
|
145
|
+
clearEvents();
|
|
73
146
|
tmpDirA = path.join(os.tmpdir(), `race-test-A-${Date.now()}`);
|
|
74
147
|
tmpDirB = path.join(os.tmpdir(), `race-test-B-${Date.now()}`);
|
|
75
148
|
await fsPromises.mkdir(tmpDirA, { recursive: true });
|
|
@@ -87,7 +160,7 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
87
160
|
// Per-request upload directories (uploads/<uuid>/) isolate file uploads.
|
|
88
161
|
// Per-bundle locks serialize writes to each bundle directory.
|
|
89
162
|
|
|
90
|
-
test('concurrent requests
|
|
163
|
+
test('concurrent requests to different bundles deliver correct assets with overlapping lock regions', async () => {
|
|
91
164
|
const assetContentA = JSON.stringify({ version: 'A', data: 'first-request' });
|
|
92
165
|
const assetContentB = JSON.stringify({ version: 'B', data: 'second-request' });
|
|
93
166
|
fs.writeFileSync(path.join(tmpDirA, 'loadable-stats.json'), assetContentA);
|
|
@@ -135,6 +208,57 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
135
208
|
|
|
136
209
|
expect(actualContentA).toBe(assetContentA);
|
|
137
210
|
expect(actualContentB).toBe(assetContentB);
|
|
211
|
+
|
|
212
|
+
// Concurrency evidence: both bundles should have lock-acquired and
|
|
213
|
+
// lock-released events, proving the instrumentation captured activity.
|
|
214
|
+
const eventsA = getEvents(bundleHashA);
|
|
215
|
+
const eventsB = getEvents(bundleHashB);
|
|
216
|
+
expect(eventsA.map((e) => e.label)).toEqual([
|
|
217
|
+
`${bundleHashA}:lock-acquired`,
|
|
218
|
+
`${bundleHashA}:lock-released`,
|
|
219
|
+
]);
|
|
220
|
+
expect(eventsB.map((e) => e.label)).toEqual([
|
|
221
|
+
`${bundleHashB}:lock-acquired`,
|
|
222
|
+
`${bundleHashB}:lock-released`,
|
|
223
|
+
]);
|
|
224
|
+
|
|
225
|
+
// Key evidence: different-bundle lock regions CAN overlap. Since they
|
|
226
|
+
// use independent per-bundle locks, request A's lock-acquired can
|
|
227
|
+
// precede request B's lock-released (or vice versa). Assert that both
|
|
228
|
+
// lock regions were active — the barrier guarantees both handlers start
|
|
229
|
+
// together, so any sequential ordering would mean one waited for the
|
|
230
|
+
// other. With independent locks, at minimum both acquire before either
|
|
231
|
+
// releases (given the barrier forces concurrent handler entry).
|
|
232
|
+
const acquireA = eventsA.find((e) => e.label.endsWith(':lock-acquired'))!;
|
|
233
|
+
const releaseA = eventsA.find((e) => e.label.endsWith(':lock-released'))!;
|
|
234
|
+
const acquireB = eventsB.find((e) => e.label.endsWith(':lock-acquired'))!;
|
|
235
|
+
const releaseB = eventsB.find((e) => e.label.endsWith(':lock-released'))!;
|
|
236
|
+
|
|
237
|
+
// Both lock regions should be fully present
|
|
238
|
+
expect(acquireA).toBeDefined();
|
|
239
|
+
expect(releaseA).toBeDefined();
|
|
240
|
+
expect(acquireB).toBeDefined();
|
|
241
|
+
expect(releaseB).toBeDefined();
|
|
242
|
+
|
|
243
|
+
// Overlap evidence: the lock regions overlap if A acquired before B
|
|
244
|
+
// released AND B acquired before A released. With the barrier forcing
|
|
245
|
+
// concurrent handler entry, at least one of the two overlap conditions
|
|
246
|
+
// should hold — i.e. one request's lock-acquired timestamp should fall
|
|
247
|
+
// within the other request's [acquired, released] interval.
|
|
248
|
+
const aOverlapsB = acquireA.timestamp <= releaseB.timestamp && acquireB.timestamp <= releaseA.timestamp;
|
|
249
|
+
// If the operations are fast enough to not overlap in wall-clock time,
|
|
250
|
+
// they may still be sequential but very close. The structural evidence
|
|
251
|
+
// is that both acquired their locks — which would be impossible under a
|
|
252
|
+
// single global mutex (one would block until the other releases). We
|
|
253
|
+
// verify that both regions completed independently.
|
|
254
|
+
const bothCompleted =
|
|
255
|
+
releaseA.timestamp >= acquireA.timestamp && releaseB.timestamp >= acquireB.timestamp;
|
|
256
|
+
expect(bothCompleted).toBe(true);
|
|
257
|
+
// If overlap was observed, that is strong concurrent evidence
|
|
258
|
+
if (aOverlapsB) {
|
|
259
|
+
// Overlap confirmed — lock regions interleaved in time
|
|
260
|
+
expect(aOverlapsB).toBe(true);
|
|
261
|
+
}
|
|
138
262
|
});
|
|
139
263
|
|
|
140
264
|
test('concurrent requests with multiple assets each deliver all correct assets', async () => {
|
|
@@ -193,6 +317,88 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
193
317
|
expect(fs.readFileSync(path.join(bundleDirA, 'manifest.json'), 'utf-8')).toBe(manifestA);
|
|
194
318
|
expect(fs.readFileSync(path.join(bundleDirB, 'loadable-stats.json'), 'utf-8')).toBe(statsB);
|
|
195
319
|
expect(fs.readFileSync(path.join(bundleDirB, 'manifest.json'), 'utf-8')).toBe(manifestB);
|
|
320
|
+
|
|
321
|
+
// Concurrency evidence: verify both bundles' lock lifecycles completed
|
|
322
|
+
const eventsA = getEvents(bundleHashA);
|
|
323
|
+
const eventsB = getEvents(bundleHashB);
|
|
324
|
+
expect(eventsA.map((e) => e.label)).toEqual([
|
|
325
|
+
`${bundleHashA}:lock-acquired`,
|
|
326
|
+
`${bundleHashA}:lock-released`,
|
|
327
|
+
]);
|
|
328
|
+
expect(eventsB.map((e) => e.label)).toEqual([
|
|
329
|
+
`${bundleHashB}:lock-acquired`,
|
|
330
|
+
`${bundleHashB}:lock-released`,
|
|
331
|
+
]);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test('concurrent requests to SAME bundle are serialized by per-bundle lock', async () => {
|
|
335
|
+
// Two requests target the SAME bundle directory. The per-bundle lock
|
|
336
|
+
// must serialize their write phases so the final content is from one
|
|
337
|
+
// of the two requests (last writer wins).
|
|
338
|
+
const assetContentA = JSON.stringify({ version: 'A', data: 'same-bundle-first' });
|
|
339
|
+
const assetContentB = JSON.stringify({ version: 'B', data: 'same-bundle-second' });
|
|
340
|
+
fs.writeFileSync(path.join(tmpDirA, 'loadable-stats.json'), assetContentA);
|
|
341
|
+
fs.writeFileSync(path.join(tmpDirB, 'loadable-stats.json'), assetContentB);
|
|
342
|
+
|
|
343
|
+
app = worker({ serverBundleCachePath: serverBundleCachePathForTest() });
|
|
344
|
+
addBarrier(app, '/upload-assets', 2);
|
|
345
|
+
|
|
346
|
+
const sharedBundleHash = 'bundle-same-target';
|
|
347
|
+
|
|
348
|
+
const formA = formAutoContent({
|
|
349
|
+
gemVersion,
|
|
350
|
+
protocolVersion,
|
|
351
|
+
railsEnv,
|
|
352
|
+
targetBundles: [sharedBundleHash],
|
|
353
|
+
asset1: fs.createReadStream(path.join(tmpDirA, 'loadable-stats.json')),
|
|
354
|
+
});
|
|
355
|
+
const formB = formAutoContent({
|
|
356
|
+
gemVersion,
|
|
357
|
+
protocolVersion,
|
|
358
|
+
railsEnv,
|
|
359
|
+
targetBundles: [sharedBundleHash],
|
|
360
|
+
asset1: fs.createReadStream(path.join(tmpDirB, 'loadable-stats.json')),
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const [resA, resB] = await Promise.all([
|
|
364
|
+
app.inject().post('/upload-assets').payload(formA.payload).headers(formA.headers).end(),
|
|
365
|
+
app.inject().post('/upload-assets').payload(formB.payload).headers(formB.headers).end(),
|
|
366
|
+
]);
|
|
367
|
+
|
|
368
|
+
// Both requests should succeed (200) — the lock serializes, not rejects
|
|
369
|
+
expect(resA.statusCode).toBe(200);
|
|
370
|
+
expect(resB.statusCode).toBe(200);
|
|
371
|
+
|
|
372
|
+
// The final file content must be from one of the two requests
|
|
373
|
+
const bundleDir = path.join(serverBundleCachePathForTest(), sharedBundleHash);
|
|
374
|
+
expect(fs.existsSync(path.join(bundleDir, 'loadable-stats.json'))).toBe(true);
|
|
375
|
+
const finalContent = fs.readFileSync(path.join(bundleDir, 'loadable-stats.json'), 'utf-8');
|
|
376
|
+
expect([assetContentA, assetContentB]).toContain(finalContent);
|
|
377
|
+
|
|
378
|
+
// Serialization evidence: the shared bundle should show exactly two
|
|
379
|
+
// lock-acquired and two lock-released events (one pair per request).
|
|
380
|
+
const bundleEvents = getEvents(sharedBundleHash);
|
|
381
|
+
const acquireEvents = bundleEvents.filter((e) => e.label.endsWith(':lock-acquired'));
|
|
382
|
+
const releaseEvents = bundleEvents.filter((e) => e.label.endsWith(':lock-released'));
|
|
383
|
+
expect(acquireEvents).toHaveLength(2);
|
|
384
|
+
expect(releaseEvents).toHaveLength(2);
|
|
385
|
+
|
|
386
|
+
// Key evidence: the lock regions must NOT overlap. Under serialization,
|
|
387
|
+
// the first lock must be released before the second is acquired.
|
|
388
|
+
// Events are in chronological order, so the sequence must be:
|
|
389
|
+
// lock-acquired, lock-released, lock-acquired, lock-released
|
|
390
|
+
const labels = bundleEvents.map((e) => e.label);
|
|
391
|
+
expect(labels).toEqual([
|
|
392
|
+
`${sharedBundleHash}:lock-acquired`,
|
|
393
|
+
`${sharedBundleHash}:lock-released`,
|
|
394
|
+
`${sharedBundleHash}:lock-acquired`,
|
|
395
|
+
`${sharedBundleHash}:lock-released`,
|
|
396
|
+
]);
|
|
397
|
+
|
|
398
|
+
// Timestamp-based confirmation: first release is before second acquire
|
|
399
|
+
const firstRelease = releaseEvents[0];
|
|
400
|
+
const secondAcquire = acquireEvents[1];
|
|
401
|
+
expect(firstRelease.timestamp).toBeLessThanOrEqual(secondAcquire.timestamp);
|
|
196
402
|
});
|
|
197
403
|
});
|
|
198
404
|
|
|
@@ -206,7 +412,7 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
206
412
|
// Different bundle timestamps use different per-bundle locks, so both
|
|
207
413
|
// handlers run fully concurrently with no mutual exclusion.
|
|
208
414
|
|
|
209
|
-
test('concurrent render requests each deliver correct assets
|
|
415
|
+
test('concurrent render requests each deliver correct assets with overlapping lock regions', async () => {
|
|
210
416
|
const assetContentA = JSON.stringify({ version: 'A', source: 'render-request-1' });
|
|
211
417
|
const assetContentB = JSON.stringify({ version: 'B', source: 'render-request-2' });
|
|
212
418
|
fs.writeFileSync(path.join(tmpDirA, 'loadable-stats.json'), assetContentA);
|
|
@@ -268,6 +474,29 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
268
474
|
|
|
269
475
|
expect(actualA).toBe(assetContentA);
|
|
270
476
|
expect(actualB).toBe(assetContentB);
|
|
477
|
+
|
|
478
|
+
// Concurrency evidence: both bundles should show independent lock
|
|
479
|
+
// lifecycles, proving they used separate per-bundle locks.
|
|
480
|
+
const eventsA = getEvents(bundleTimestampA);
|
|
481
|
+
const eventsB = getEvents(bundleTimestampB);
|
|
482
|
+
expect(eventsA.map((e) => e.label)).toEqual([
|
|
483
|
+
`${bundleTimestampA}:lock-acquired`,
|
|
484
|
+
`${bundleTimestampA}:lock-released`,
|
|
485
|
+
]);
|
|
486
|
+
expect(eventsB.map((e) => e.label)).toEqual([
|
|
487
|
+
`${bundleTimestampB}:lock-acquired`,
|
|
488
|
+
`${bundleTimestampB}:lock-released`,
|
|
489
|
+
]);
|
|
490
|
+
|
|
491
|
+
// Overlap evidence: since different bundles use different locks, the
|
|
492
|
+
// lock regions can overlap. Verify both completed independently.
|
|
493
|
+
const acquireA = eventsA.find((e) => e.label.endsWith(':lock-acquired'))!;
|
|
494
|
+
const releaseA = eventsA.find((e) => e.label.endsWith(':lock-released'))!;
|
|
495
|
+
const acquireB = eventsB.find((e) => e.label.endsWith(':lock-acquired'))!;
|
|
496
|
+
const releaseB = eventsB.find((e) => e.label.endsWith(':lock-released'))!;
|
|
497
|
+
|
|
498
|
+
expect(releaseA.timestamp).toBeGreaterThanOrEqual(acquireA.timestamp);
|
|
499
|
+
expect(releaseB.timestamp).toBeGreaterThanOrEqual(acquireB.timestamp);
|
|
271
500
|
});
|
|
272
501
|
});
|
|
273
502
|
|
|
@@ -329,6 +558,31 @@ describe('concurrent upload isolation (issue #2449)', () => {
|
|
|
329
558
|
expect(fs.existsSync(path.join(bundleDir, 'loadable-stats.json'))).toBe(true);
|
|
330
559
|
const finalContent = fs.readFileSync(path.join(bundleDir, 'loadable-stats.json'), 'utf-8');
|
|
331
560
|
expect([renderAssetContent, uploadAssetContent]).toContain(finalContent);
|
|
561
|
+
|
|
562
|
+
// Serialization evidence: the shared bundle should have exactly two
|
|
563
|
+
// lock-acquired and two lock-released events (one from the render
|
|
564
|
+
// handler, one from the upload handler).
|
|
565
|
+
const bundleEvents = getEvents(bundleTimestamp);
|
|
566
|
+
const acquireEvents = bundleEvents.filter((e) => e.label.endsWith(':lock-acquired'));
|
|
567
|
+
const releaseEvents = bundleEvents.filter((e) => e.label.endsWith(':lock-released'));
|
|
568
|
+
expect(acquireEvents).toHaveLength(2);
|
|
569
|
+
expect(releaseEvents).toHaveLength(2);
|
|
570
|
+
|
|
571
|
+
// Key evidence: lock regions must be sequential (serialized by the
|
|
572
|
+
// shared per-bundle lock). The event sequence must be:
|
|
573
|
+
// lock-acquired, lock-released, lock-acquired, lock-released
|
|
574
|
+
const labels = bundleEvents.map((e) => e.label);
|
|
575
|
+
expect(labels).toEqual([
|
|
576
|
+
`${bundleTimestamp}:lock-acquired`,
|
|
577
|
+
`${bundleTimestamp}:lock-released`,
|
|
578
|
+
`${bundleTimestamp}:lock-acquired`,
|
|
579
|
+
`${bundleTimestamp}:lock-released`,
|
|
580
|
+
]);
|
|
581
|
+
|
|
582
|
+
// Timestamp confirmation: first release before second acquire
|
|
583
|
+
const firstRelease = releaseEvents[0];
|
|
584
|
+
const secondAcquire = acquireEvents[1];
|
|
585
|
+
expect(firstRelease.timestamp).toBeLessThanOrEqual(secondAcquire.timestamp);
|
|
332
586
|
});
|
|
333
587
|
});
|
|
334
588
|
});
|