@salesforce/pwa-kit-runtime 3.9.0 → 3.9.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/pwa-kit-runtime",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.2",
|
|
4
4
|
"description": "The PWAKit Runtime",
|
|
5
5
|
"homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-runtime#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@loadable/component": "^5.15.3",
|
|
49
|
-
"@salesforce/pwa-kit-dev": "3.9.
|
|
49
|
+
"@salesforce/pwa-kit-dev": "3.9.2",
|
|
50
50
|
"@serverless/event-mocks": "^1.1.1",
|
|
51
51
|
"aws-lambda-mock-context": "^3.2.1",
|
|
52
52
|
"fs-extra": "^11.1.1",
|
|
53
|
-
"internal-lib-build": "3.9.
|
|
53
|
+
"internal-lib-build": "3.9.2",
|
|
54
54
|
"nock": "^13.3.0",
|
|
55
55
|
"nodemon": "^2.0.22",
|
|
56
56
|
"sinon": "^13.0.2",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"supertest": "^4.0.2"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@salesforce/pwa-kit-dev": "3.9.
|
|
61
|
+
"@salesforce/pwa-kit-dev": "3.9.2"
|
|
62
62
|
},
|
|
63
63
|
"peerDependenciesMeta": {
|
|
64
64
|
"@salesforce/pwa-kit-dev": {
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"directory": "dist"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "d982971e3a1cc1f65ce296e526c459b2ea5f83fe"
|
|
76
76
|
}
|
|
@@ -319,6 +319,8 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
319
319
|
app.disable('x-powered-by');
|
|
320
320
|
const mixin = {
|
|
321
321
|
options,
|
|
322
|
+
// Forcing a GC is no longer necessary, and will be
|
|
323
|
+
// skipped by default (unless FORCE_GC env-var is set).
|
|
322
324
|
_collectGarbage() {
|
|
323
325
|
// Do global.gc in a separate 'then' handler so
|
|
324
326
|
// that all major variables are out of scope and
|
|
@@ -883,12 +885,15 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
883
885
|
// the response to the browser.
|
|
884
886
|
context.callbackWaitsForEmptyEventLoop = false;
|
|
885
887
|
if (lambdaContainerReused) {
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
888
|
+
const forceGarbageCollection = process.env.FORCE_GC;
|
|
889
|
+
if (forceGarbageCollection && forceGarbageCollection.toLowerCase() === 'true') {
|
|
890
|
+
// DESKTOP-434 If this Lambda container is being reused,
|
|
891
|
+
// clean up memory now, so that we start with low usage.
|
|
892
|
+
// These regular GC calls take about 80-100 mS each, as opposed
|
|
893
|
+
// to forced GC calls, which occur randomly and can take several
|
|
894
|
+
// hundred mS.
|
|
895
|
+
app._collectGarbage();
|
|
896
|
+
}
|
|
892
897
|
app.sendMetric('LambdaReused');
|
|
893
898
|
} else {
|
|
894
899
|
// This is the first use of this container, so set the
|
|
@@ -54,6 +54,54 @@ const testFixtures = path.resolve(process.cwd(), 'src/ssr/server/test_fixtures')
|
|
|
54
54
|
const httpsAgent = new https.Agent({
|
|
55
55
|
rejectUnauthorized: false
|
|
56
56
|
});
|
|
57
|
+
function createServerWithGCSpy() {
|
|
58
|
+
const route = jest.fn((req, res) => {
|
|
59
|
+
res.send('<html/>');
|
|
60
|
+
});
|
|
61
|
+
const options = {
|
|
62
|
+
buildDir: testFixtures,
|
|
63
|
+
mobify: testPackageMobify,
|
|
64
|
+
sslFilePath: path.join(testFixtures, 'localhost.pem'),
|
|
65
|
+
quiet: true,
|
|
66
|
+
port: TEST_PORT,
|
|
67
|
+
fetchAgents: {
|
|
68
|
+
https: httpsAgent
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const {
|
|
72
|
+
handler,
|
|
73
|
+
server,
|
|
74
|
+
app
|
|
75
|
+
} = RemoteServerFactory.createHandler(options, app => {
|
|
76
|
+
app.get('/*', route);
|
|
77
|
+
});
|
|
78
|
+
const collectGarbage = jest.spyOn(app, '_collectGarbage');
|
|
79
|
+
const sendMetric = jest.spyOn(app, 'sendMetric');
|
|
80
|
+
return {
|
|
81
|
+
route,
|
|
82
|
+
handler,
|
|
83
|
+
collectGarbage,
|
|
84
|
+
sendMetric,
|
|
85
|
+
server
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function createApiGatewayEvent() {
|
|
89
|
+
// Set up a fake event and a fake context for the Lambda call
|
|
90
|
+
const event = createEvent('aws:apiGateway', {
|
|
91
|
+
path: '/',
|
|
92
|
+
body: undefined
|
|
93
|
+
});
|
|
94
|
+
if (event.queryStringParameters) {
|
|
95
|
+
delete event.queryStringParameters;
|
|
96
|
+
}
|
|
97
|
+
const context = AWSMockContext({
|
|
98
|
+
functionName: 'SSRTest'
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
event,
|
|
102
|
+
context
|
|
103
|
+
};
|
|
104
|
+
}
|
|
57
105
|
describe('SSRServer Lambda integration', () => {
|
|
58
106
|
let savedEnvironment;
|
|
59
107
|
let server;
|
|
@@ -329,42 +377,50 @@ describe('SSRServer Lambda integration', () => {
|
|
|
329
377
|
X_HEADERS_TO_REMOVE_ORIGIN.forEach(key => expect(reqHeaders[key]).toBeUndefined());
|
|
330
378
|
});
|
|
331
379
|
});
|
|
332
|
-
test('Lambda reuse
|
|
333
|
-
const route = jest.fn((req, res) => {
|
|
334
|
-
res.send('<html/>');
|
|
335
|
-
});
|
|
336
|
-
const options = {
|
|
337
|
-
buildDir: testFixtures,
|
|
338
|
-
mobify: testPackageMobify,
|
|
339
|
-
sslFilePath: path.join(testFixtures, 'localhost.pem'),
|
|
340
|
-
quiet: true,
|
|
341
|
-
port: TEST_PORT,
|
|
342
|
-
fetchAgents: {
|
|
343
|
-
https: httpsAgent
|
|
344
|
-
}
|
|
345
|
-
};
|
|
380
|
+
test('Lambda reuse -- Default Behavior', () => {
|
|
346
381
|
const {
|
|
347
|
-
|
|
382
|
+
route,
|
|
348
383
|
handler,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
});
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
384
|
+
collectGarbage,
|
|
385
|
+
sendMetric,
|
|
386
|
+
new_server
|
|
387
|
+
} = createServerWithGCSpy();
|
|
388
|
+
const {
|
|
389
|
+
event,
|
|
390
|
+
context
|
|
391
|
+
} = createApiGatewayEvent();
|
|
392
|
+
server = new_server;
|
|
393
|
+
const call = event => new Promise(resolve => handler(event, context, (err, response) => resolve(response)));
|
|
394
|
+
return Promise.resolve().then(() => call(event)).then(response => {
|
|
395
|
+
// First request - Lambda container created
|
|
396
|
+
expect(response.statusCode).toBe(200);
|
|
397
|
+
expect(collectGarbage.mock.calls).toHaveLength(0);
|
|
398
|
+
expect(route.mock.calls).toHaveLength(1);
|
|
399
|
+
expect(sendMetric).toHaveBeenCalledWith('LambdaCreated');
|
|
400
|
+
expect(sendMetric).not.toHaveBeenCalledWith('LambdaReused');
|
|
401
|
+
}).then(() => call(event)).then(response => {
|
|
402
|
+
// Second call - Lambda container reused
|
|
403
|
+
expect(response.statusCode).toBe(200);
|
|
404
|
+
expect(collectGarbage.mock.calls).toHaveLength(0);
|
|
405
|
+
expect(route.mock.calls).toHaveLength(2);
|
|
406
|
+
expect(sendMetric).toHaveBeenCalledWith('LambdaCreated');
|
|
407
|
+
expect(sendMetric).toHaveBeenCalledWith('LambdaReused');
|
|
367
408
|
});
|
|
409
|
+
});
|
|
410
|
+
test('Lambda reuse -- with Forced Garbage Collection Enabled', () => {
|
|
411
|
+
process.env.FORCE_GC = 'true';
|
|
412
|
+
const {
|
|
413
|
+
event,
|
|
414
|
+
context
|
|
415
|
+
} = createApiGatewayEvent();
|
|
416
|
+
const {
|
|
417
|
+
route,
|
|
418
|
+
handler,
|
|
419
|
+
collectGarbage,
|
|
420
|
+
sendMetric,
|
|
421
|
+
new_server
|
|
422
|
+
} = createServerWithGCSpy();
|
|
423
|
+
server = new_server;
|
|
368
424
|
const call = event => new Promise(resolve => handler(event, context, (err, response) => resolve(response)));
|
|
369
425
|
return Promise.resolve().then(() => call(event)).then(response => {
|
|
370
426
|
// First request - Lambda container created
|
|
@@ -59,7 +59,11 @@ class MetricsSender {
|
|
|
59
59
|
apiVersion: '2010-08-01',
|
|
60
60
|
// The AWS_REGION variable is defined by the Lambda
|
|
61
61
|
// environment.
|
|
62
|
-
region: process.env.AWS_REGION || 'us-east-1'
|
|
62
|
+
region: process.env.AWS_REGION || 'us-east-1',
|
|
63
|
+
// Setting maxRetries to 0 will prevent the SDK from retrying.
|
|
64
|
+
// This is necessary because under high load, there will be backpressure
|
|
65
|
+
// on the Lambda function, and causing severe performance issues (400-500ms latency)
|
|
66
|
+
maxRetries: 0
|
|
63
67
|
});
|
|
64
68
|
}
|
|
65
69
|
return this._CW;
|