canopycms-cdk 0.0.68-int.97 → 0.0.68-int.98
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.
|
@@ -88,10 +88,9 @@ const TRANSFORM_LAMBDA_TIMEOUT = Duration.seconds(30);
|
|
|
88
88
|
*
|
|
89
89
|
* A reservation is a CAP carved from the account's concurrency pool, not
|
|
90
90
|
* pre-warmed capacity, so it costs nothing when idle (that is
|
|
91
|
-
* `provisionedConcurrentExecutions`, which this is not).
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* invoking this function at all.
|
|
91
|
+
* `provisionedConcurrentExecutions`, which this is not). Genuine demand is
|
|
92
|
+
* first-render misses only, since every already-generated derivative is served
|
|
93
|
+
* by the S3 primary origin without invoking this function at all.
|
|
95
94
|
*/
|
|
96
95
|
const TRANSFORM_LAMBDA_RESERVED_CONCURRENCY = 10;
|
|
97
96
|
/**
|
|
@@ -21,6 +21,15 @@ import type { CanopyCmsAttachOptions } from './editor-routing.js';
|
|
|
21
21
|
* than deploying a configuration that would 504.
|
|
22
22
|
*/
|
|
23
23
|
export declare const DEFAULT_CMS_LAMBDA_TIMEOUT: Duration;
|
|
24
|
+
/**
|
|
25
|
+
* The cap below which synth warns. With nothing cached, a cold editor load on
|
|
26
|
+
* the example app sends the Lambda about 25 requests, 14 of them chunks
|
|
27
|
+
* requested together, and each invocation holds an execution environment
|
|
28
|
+
* through its cold start.
|
|
29
|
+
*/
|
|
30
|
+
export declare const MIN_CMS_RESERVED_CONCURRENCY = 20;
|
|
31
|
+
/** Default `reservedConcurrency`; see that prop for what it caps and costs. */
|
|
32
|
+
export declare const DEFAULT_CMS_RESERVED_CONCURRENCY = 50;
|
|
24
33
|
export interface CanopyCmsServiceProps {
|
|
25
34
|
/** Docker image for the CMS Lambda function */
|
|
26
35
|
cmsDockerImage: lambda.DockerImageCode;
|
|
@@ -30,7 +39,24 @@ export interface CanopyCmsServiceProps {
|
|
|
30
39
|
memorySize?: number;
|
|
31
40
|
/** Lambda timeout (default: 60 seconds) */
|
|
32
41
|
timeout?: Duration;
|
|
33
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Cap on the CMS Lambda's concurrent invocations (default: 50).
|
|
44
|
+
*
|
|
45
|
+
* Everything the Lambda serves counts against it, including the editor's
|
|
46
|
+
* static chunks (`editorAssetPrefix` on `attachTo`, `/_next/static/*` on
|
|
47
|
+
* `CanopyCmsDistribution`) whenever CloudFront misses them. CloudFront caches
|
|
48
|
+
* per regional edge cache, so after a deploy the first editor load behind
|
|
49
|
+
* each one requests every chunk together, and an invocation over the cap is
|
|
50
|
+
* answered 429: the
|
|
51
|
+
* browser refuses that as a script and the editor fails with
|
|
52
|
+
* `ChunkLoadError`. Synth warns below {@link MIN_CMS_RESERVED_CONCURRENCY}.
|
|
53
|
+
*
|
|
54
|
+
* A reservation costs nothing while idle; it is a ceiling, and a share of
|
|
55
|
+
* the account's concurrency set aside so other functions cannot use it.
|
|
56
|
+
* Lambda keeps 100 of the account's limit unreserved, so this plus every
|
|
57
|
+
* other reservation (AssetSupport's transform Lambda reserves 10) must fit
|
|
58
|
+
* within the account limit minus 100.
|
|
59
|
+
*/
|
|
34
60
|
reservedConcurrency?: number;
|
|
35
61
|
/**
|
|
36
62
|
* Lambda architecture (default: `Architecture.ARM_64`, matching the EC2
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { Construct } from 'constructs';
|
|
4
|
-
import { Duration, RemovalPolicy, Stack, Token, aws_ec2 as ec2, aws_efs as efs, aws_iam as iam, aws_lambda as lambda, aws_autoscaling as autoscaling, aws_s3_assets as s3assets, aws_logs as logs, } from 'aws-cdk-lib';
|
|
4
|
+
import { Annotations, Duration, RemovalPolicy, Stack, Token, aws_ec2 as ec2, aws_efs as efs, aws_iam as iam, aws_lambda as lambda, aws_autoscaling as autoscaling, aws_s3_assets as s3assets, aws_logs as logs, } from 'aws-cdk-lib';
|
|
5
5
|
import { attachLambdaExecutionPolicies } from './lambda-execution-role.js';
|
|
6
6
|
import { attachEditorBehaviors } from './editor-routing.js';
|
|
7
7
|
// This package (`canopycms-cdk`) is `"type": "module"`, so its compiled output
|
|
@@ -465,6 +465,15 @@ function assertGitHubAuthProps(props) {
|
|
|
465
465
|
* than deploying a configuration that would 504.
|
|
466
466
|
*/
|
|
467
467
|
export const DEFAULT_CMS_LAMBDA_TIMEOUT = Duration.seconds(60);
|
|
468
|
+
/**
|
|
469
|
+
* The cap below which synth warns. With nothing cached, a cold editor load on
|
|
470
|
+
* the example app sends the Lambda about 25 requests, 14 of them chunks
|
|
471
|
+
* requested together, and each invocation holds an execution environment
|
|
472
|
+
* through its cold start.
|
|
473
|
+
*/
|
|
474
|
+
export const MIN_CMS_RESERVED_CONCURRENCY = 20;
|
|
475
|
+
/** Default `reservedConcurrency`; see that prop for what it caps and costs. */
|
|
476
|
+
export const DEFAULT_CMS_RESERVED_CONCURRENCY = 50;
|
|
468
477
|
/**
|
|
469
478
|
* Core CDK construct for CanopyCMS deployment.
|
|
470
479
|
*
|
|
@@ -686,6 +695,14 @@ export class CanopyCmsService extends Construct {
|
|
|
686
695
|
// Silicon, amd64 on an x86 CI runner) while the function stays x86_64, and
|
|
687
696
|
// the mismatch only shows at invoke. See `architecture`'s doc comment.
|
|
688
697
|
const architecture = props.architecture ?? lambda.Architecture.ARM_64;
|
|
698
|
+
const reservedConcurrency = props.reservedConcurrency ?? DEFAULT_CMS_RESERVED_CONCURRENCY;
|
|
699
|
+
if (!Token.isUnresolved(reservedConcurrency) &&
|
|
700
|
+
reservedConcurrency < MIN_CMS_RESERVED_CONCURRENCY) {
|
|
701
|
+
Annotations.of(this).addWarningV2('canopycms:cms-reserved-concurrency-low', `reservedConcurrency is ${reservedConcurrency}, below ${MIN_CMS_RESERVED_CONCURRENCY}. ` +
|
|
702
|
+
`The editor's static chunks are served by this Lambda until CloudFront caches them, ` +
|
|
703
|
+
`and a cold editor load requests them together, so a throttled chunk fails the ` +
|
|
704
|
+
`editor with ChunkLoadError. See the reservedConcurrency prop.`);
|
|
705
|
+
}
|
|
689
706
|
this.lambdaFunction = new lambda.DockerImageFunction(this, 'CmsFunction', {
|
|
690
707
|
code: props.cmsDockerImage,
|
|
691
708
|
// Default (unset) leaves CDK to create the execution role, with its own
|
|
@@ -693,7 +710,7 @@ export class CanopyCmsService extends Construct {
|
|
|
693
710
|
role: props.lambdaRole,
|
|
694
711
|
memorySize: props.memorySize ?? 2048,
|
|
695
712
|
timeout: this.timeout,
|
|
696
|
-
reservedConcurrentExecutions:
|
|
713
|
+
reservedConcurrentExecutions: reservedConcurrency,
|
|
697
714
|
architecture,
|
|
698
715
|
vpc: this.vpc,
|
|
699
716
|
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
|
|
@@ -4522,7 +4522,7 @@ var init_config = __esm({
|
|
|
4522
4522
|
title: external_exports.string().optional(),
|
|
4523
4523
|
subtitle: external_exports.string().optional(),
|
|
4524
4524
|
theme: external_exports.unknown().optional(),
|
|
4525
|
-
previewBase: external_exports.record(external_exports.string()).optional(),
|
|
4525
|
+
previewBase: external_exports.record(external_exports.union([external_exports.string(), external_exports.literal(false)])).optional(),
|
|
4526
4526
|
previewPrefix: previewPrefixSchema.optional(),
|
|
4527
4527
|
// UI handler functions (runtime only, don't serialize)
|
|
4528
4528
|
onAccountClick: external_exports.function().returns(external_exports.void()).optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canopycms-cdk",
|
|
3
|
-
"version": "0.0.68-int.
|
|
3
|
+
"version": "0.0.68-int.98",
|
|
4
4
|
"description": "AWS CDK constructs and EC2 worker for CanopyCMS deployment",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"aws-cdk-lib": "^2.260.0",
|
|
33
33
|
"constructs": "^10.0.0",
|
|
34
|
-
"canopycms": "0.0.68-int.
|
|
34
|
+
"canopycms": "0.0.68-int.98"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"aws-cdk-lib": {
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"tsx": "^4.19.0",
|
|
57
57
|
"typescript": "^5.6.3",
|
|
58
58
|
"vitest": "^4.1.0",
|
|
59
|
-
"canopycms": "0.0.68-int.
|
|
60
|
-
"canopycms-auth-clerk": "0.0.68-int.
|
|
59
|
+
"canopycms": "0.0.68-int.98",
|
|
60
|
+
"canopycms-auth-clerk": "0.0.68-int.98"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "rm -rf dist && tsc && node ../../scripts/add-js-extensions.mjs dist",
|
package/worker/dist/index.js
CHANGED
|
@@ -12515,7 +12515,7 @@ var init_config2 = __esm({
|
|
|
12515
12515
|
title: external_exports.string().optional(),
|
|
12516
12516
|
subtitle: external_exports.string().optional(),
|
|
12517
12517
|
theme: external_exports.unknown().optional(),
|
|
12518
|
-
previewBase: external_exports.record(external_exports.string()).optional(),
|
|
12518
|
+
previewBase: external_exports.record(external_exports.union([external_exports.string(), external_exports.literal(false)])).optional(),
|
|
12519
12519
|
previewPrefix: previewPrefixSchema.optional(),
|
|
12520
12520
|
// UI handler functions (runtime only, don't serialize)
|
|
12521
12521
|
onAccountClick: external_exports.function().returns(external_exports.void()).optional(),
|
|
@@ -48958,7 +48958,7 @@ async function writeWorkerStatus(taskDir, report) {
|
|
|
48958
48958
|
}
|
|
48959
48959
|
|
|
48960
48960
|
// ../canopycms/src/version.ts
|
|
48961
|
-
var CANOPYCMS_VERSION = "0.0.68-int.
|
|
48961
|
+
var CANOPYCMS_VERSION = "0.0.68-int.98";
|
|
48962
48962
|
|
|
48963
48963
|
// ../canopycms/src/worker/log.ts
|
|
48964
48964
|
init_logger();
|