Skip to content

Commit c28e45e

Browse files
authored
feat(commons): make utilities aware of provisioned concurrency (#3724)
1 parent 61725f4 commit c28e45e

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

Diff for: packages/commons/src/Utility.ts

+31
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,46 @@
5151
* ```
5252
*/
5353
export class Utility {
54+
readonly #initializationType:
55+
| 'unknown'
56+
| 'on-demand'
57+
| 'provisioned-concurrency';
5458
protected coldStart = true;
5559
protected readonly defaultServiceName: string = 'service_undefined';
5660

61+
public constructor() {
62+
this.#initializationType = this.getInitializationType();
63+
if (this.#initializationType !== 'on-demand') {
64+
this.coldStart = false;
65+
}
66+
}
67+
68+
/**
69+
* Get the value of the `AWS_LAMBDA_INITIALIZATION_TYPE` environment variable.
70+
*/
71+
protected getInitializationType():
72+
| 'unknown'
73+
| 'on-demand'
74+
| 'provisioned-concurrency' {
75+
const envVarValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE?.trim();
76+
if (envVarValue === 'on-demand') {
77+
return 'on-demand';
78+
}
79+
if (envVarValue === 'provisioned-concurrency') {
80+
return 'provisioned-concurrency';
81+
}
82+
return 'unknown';
83+
}
84+
5785
/**
5886
* Get the cold start status of the current execution environment.
5987
*
6088
* The method also flips the cold start status to `false` after the first invocation.
6189
*/
6290
protected getColdStart(): boolean {
91+
if (this.#initializationType !== 'on-demand') {
92+
return false;
93+
}
6394
if (this.coldStart) {
6495
this.coldStart = false;
6596

Diff for: packages/commons/tests/unit/Utility.test.ts

+34
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ describe('Class: Utility', () => {
1515
public validateServiceName(serviceName: string): boolean {
1616
return this.isValidServiceName(serviceName);
1717
}
18+
public getInitializationType():
19+
| 'unknown'
20+
| 'on-demand'
21+
| 'provisioned-concurrency' {
22+
return super.getInitializationType();
23+
}
1824
}
1925

2026
it('returns the correct cold start value', () => {
@@ -27,6 +33,15 @@ describe('Class: Utility', () => {
2733
expect(utility.dummyMethod()).toBe(false);
2834
});
2935

36+
it('returns the correct cold start value when provisioned concurrency is used', () => {
37+
// Prepare
38+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = 'provisioned-concurrency';
39+
const utility = new TestUtility();
40+
41+
// Act & Assess
42+
expect(utility.dummyMethod()).toBe(false);
43+
});
44+
3045
it('flips the cold start value', () => {
3146
// Prepare
3247
const utility = new TestUtility();
@@ -54,4 +69,23 @@ describe('Class: Utility', () => {
5469
expect(utility.validateServiceName('serverlessAirline')).toBe(true);
5570
expect(utility.validateServiceName('')).toBe(false);
5671
});
72+
73+
it.each([
74+
{ value: 'on-demand', expected: 'on-demand' },
75+
{ value: 'provisioned-concurrency', expected: 'provisioned-concurrency' },
76+
{ value: '', expected: 'unknown' },
77+
])(
78+
'returns the correct initialization type ($value)',
79+
({ value, expected }) => {
80+
// Prepare
81+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = value;
82+
const utility = new TestUtility();
83+
84+
// Act
85+
const initializationType = utility.getInitializationType();
86+
87+
// Assess
88+
expect(initializationType).toBe(expected);
89+
}
90+
);
5791
});

Diff for: packages/commons/tests/unit/awsSdkUtils.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import {
66
PT_VERSION as version,
77
} from '../../src/index.js';
88

9+
vi.hoisted(() => {
10+
process.env.AWS_EXECUTION_ENV = '';
11+
});
12+
913
describe('Helpers: awsSdk', () => {
1014
describe('Function: userAgentMiddleware', () => {
1115
beforeAll(() => {

Diff for: packages/commons/vitest.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config';
33
export default defineProject({
44
test: {
55
environment: 'node',
6+
setupFiles: ['../testing/src/setupEnv.ts'],
67
},
78
});

Diff for: packages/logger/tests/e2e/advancedUses.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { RESOURCE_NAME_PREFIX, STACK_OUTPUT_LOG_GROUP } from './constants.js';
1212
* In this e2e test for Logger, we test a number of advanced use cases:
1313
* - Log buffering enabled with flush on error (both manually on logger.error and automatically on uncaught error)
1414
* - Correlation ID injection (both manually and automatically)
15+
* - Cold start detection for provisioned concurrency (always false)
1516
*
1617
* The test is split into three cases:
1718
* - Manual instrumentation
@@ -127,6 +128,7 @@ describe('Logger E2E - Advanced uses', () => {
127128
expect.objectContaining({
128129
level: 'INFO',
129130
message: 'an info log',
131+
cold_start: false,
130132
correlation_id: correlationId,
131133
})
132134
);
@@ -136,6 +138,7 @@ describe('Logger E2E - Advanced uses', () => {
136138
expect.objectContaining({
137139
level: 'DEBUG',
138140
message: 'a buffered debug log',
141+
cold_start: false,
139142
correlation_id: correlationId,
140143
})
141144
);
@@ -145,6 +148,7 @@ describe('Logger E2E - Advanced uses', () => {
145148
expect.objectContaining({
146149
level: 'ERROR',
147150
message: 'Uncaught error detected, flushing log buffer before exit',
151+
cold_start: false,
148152
correlation_id: correlationId,
149153
error: expect.objectContaining({
150154
name: 'Error',

0 commit comments

Comments
 (0)