@friggframework/devtools 2.0.0--canary.580.f1cb41c.0 → 2.0.0--canary.5ff5209.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.
|
@@ -21,6 +21,36 @@ const AuroraResourceResolver = require('./aurora-resolver');
|
|
|
21
21
|
const { createEmptyDiscoveryResult } = require('../shared/types/discovery-result');
|
|
22
22
|
const { ResourceOwnership } = require('../shared/types/resource-ownership');
|
|
23
23
|
|
|
24
|
+
// Pool + timeout query params appended to DATABASE_URL for Lambda-to-Aurora
|
|
25
|
+
// connections. Chosen to make worker Lambdas fail loud and fast on any DB
|
|
26
|
+
// contention rather than silently hanging for Lambda's 900s timeout.
|
|
27
|
+
//
|
|
28
|
+
// connection_limit=2 — two pg connections per Lambda container. One is too
|
|
29
|
+
// tight: several core use cases (get-process.executeMany,
|
|
30
|
+
// field-encryption-service batches) issue in-handler
|
|
31
|
+
// Promise.all against Prisma, and would serialize
|
|
32
|
+
// behind a single slot. Two removes that cliff while
|
|
33
|
+
// still being safe against max_connections (at 4 ACU
|
|
34
|
+
// Aurora pg 15 allows ~400 connections; 200 concurrent
|
|
35
|
+
// Lambdas × 2 = 400, leaves cluster room for maint).
|
|
36
|
+
// pool_timeout=20 — wait up to 20s for a pool slot, then throw P2024.
|
|
37
|
+
// Still fail-fast relative to 900s Lambda cap; gives
|
|
38
|
+
// in-handler fan-outs headroom.
|
|
39
|
+
// connect_timeout=10 — bound TCP/TLS handshake.
|
|
40
|
+
// socket_timeout=60 — kill dead client sockets (server never responds).
|
|
41
|
+
// options=-c statement_timeout=30000 -c lock_timeout=10000
|
|
42
|
+
// — Postgres-side hard caps. A query stuck >30s aborts
|
|
43
|
+
// with SQLSTATE 57014; a lock wait >10s aborts with
|
|
44
|
+
// SQLSTATE 55P03. URL encoding per libpq URI rules
|
|
45
|
+
// (space→%20, `=`→%3D inside the options value).
|
|
46
|
+
const LAMBDA_DATABASE_URL_QUERY_PARAMS = [
|
|
47
|
+
'connection_limit=2',
|
|
48
|
+
'pool_timeout=20',
|
|
49
|
+
'connect_timeout=10',
|
|
50
|
+
'socket_timeout=60',
|
|
51
|
+
'options=-c%20statement_timeout%3D30000%20-c%20lock_timeout%3D10000',
|
|
52
|
+
].join('&');
|
|
53
|
+
|
|
24
54
|
class AuroraBuilder extends InfrastructureBuilder {
|
|
25
55
|
constructor() {
|
|
26
56
|
super();
|
|
@@ -501,6 +531,10 @@ class AuroraBuilder extends InfrastructureBuilder {
|
|
|
501
531
|
result.environment.DATABASE_PORT = String(dbConfig.port || 5432);
|
|
502
532
|
result.environment.DATABASE_NAME = dbConfig.database || 'frigg';
|
|
503
533
|
result.environment.DATABASE_USER = dbConfig.username || 'postgres';
|
|
534
|
+
// Consumers that build DATABASE_URL from components at runtime MUST
|
|
535
|
+
// append `?${DATABASE_URL_PARAMS}` to get the same hang-prevention
|
|
536
|
+
// timeouts as the managed path.
|
|
537
|
+
result.environment.DATABASE_URL_PARAMS = LAMBDA_DATABASE_URL_QUERY_PARAMS;
|
|
504
538
|
|
|
505
539
|
console.log(` ✅ Using existing cluster: ${dbConfig.endpoint}`);
|
|
506
540
|
}
|
|
@@ -731,13 +765,18 @@ exports.handler = async (event, context) => {
|
|
|
731
765
|
result.environment.DATABASE_HOST = discoveredResources.auroraClusterEndpoint;
|
|
732
766
|
result.environment.DATABASE_PORT = String(discoveredResources.auroraPort || 5432);
|
|
733
767
|
result.environment.DATABASE_NAME = dbName;
|
|
768
|
+
// Consumers that build DATABASE_URL from components at runtime MUST
|
|
769
|
+
// append `?${DATABASE_URL_PARAMS}` to get the same hang-prevention
|
|
770
|
+
// timeouts as the managed path.
|
|
771
|
+
result.environment.DATABASE_URL_PARAMS = LAMBDA_DATABASE_URL_QUERY_PARAMS;
|
|
734
772
|
|
|
735
773
|
// Note: DATABASE_URL is NOT set here to avoid Serverless variable resolution errors
|
|
736
774
|
// The application (Frigg Core) should construct it at runtime from:
|
|
737
|
-
// DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD
|
|
775
|
+
// DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD, DATABASE_URL_PARAMS
|
|
738
776
|
|
|
739
777
|
console.log(' ℹ️ No Secrets Manager secret found - set DATABASE_USER and DATABASE_PASSWORD in Lambda environment');
|
|
740
778
|
console.log(' ℹ️ Application will construct DATABASE_URL at runtime from DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD');
|
|
779
|
+
console.log(' ℹ️ Append `?${DATABASE_URL_PARAMS}` to the constructed URL for pool/timeout safety.');
|
|
741
780
|
console.log(' ℹ️ Or enable autoCreateCredentials=true to automatically create and rotate credentials');
|
|
742
781
|
}
|
|
743
782
|
|
|
@@ -797,35 +836,11 @@ exports.handler = async (event, context) => {
|
|
|
797
836
|
return `{{resolve:secretsmanager:${secretRefValue}:SecretString:password}}`;
|
|
798
837
|
};
|
|
799
838
|
|
|
800
|
-
//
|
|
801
|
-
//
|
|
802
|
-
// rely on Lambda concurrency for parallelism
|
|
803
|
-
// rather than per-process pooling (AWS RDS/
|
|
804
|
-
// Lambda best practice).
|
|
805
|
-
// pool_timeout=10 — throw P2024 instead of waiting forever for
|
|
806
|
-
// a pool slot.
|
|
807
|
-
// connect_timeout=10 — bound TCP/TLS handshake to 10s.
|
|
808
|
-
// socket_timeout=60 — kill the client socket if the server
|
|
809
|
-
// never responds (dead NAT/VPC route case).
|
|
810
|
-
// options=-c statement_timeout=30000 -c lock_timeout=10000
|
|
811
|
-
// — Postgres-side hard caps on query and
|
|
812
|
-
// lock-wait duration; queries aborting
|
|
813
|
-
// with SQLSTATE 57014 / 55P03 surface as
|
|
814
|
-
// errors instead of 15-minute Lambda
|
|
815
|
-
// timeouts. URL-encoded per Postgres libpq
|
|
816
|
-
// conventions (space→%20, `=`→%3D inside
|
|
817
|
-
// the options value).
|
|
818
|
-
const queryParams = [
|
|
819
|
-
'connection_limit=1',
|
|
820
|
-
'pool_timeout=10',
|
|
821
|
-
'connect_timeout=10',
|
|
822
|
-
'socket_timeout=60',
|
|
823
|
-
'options=-c%20statement_timeout%3D30000%20-c%20lock_timeout%3D10000',
|
|
824
|
-
].join('&');
|
|
825
|
-
|
|
839
|
+
// Query params are defined at module scope (LAMBDA_DATABASE_URL_QUERY_PARAMS)
|
|
840
|
+
// so runtime-URL-construction paths can emit the same timeouts as an env var.
|
|
826
841
|
return {
|
|
827
842
|
'Fn::Sub': [
|
|
828
|
-
`postgresql://\${Username}:\${Password}@\${Host}:\${Port}/\${Database}?${
|
|
843
|
+
`postgresql://\${Username}:\${Password}@\${Host}:\${Port}/\${Database}?${LAMBDA_DATABASE_URL_QUERY_PARAMS}`,
|
|
829
844
|
{
|
|
830
845
|
Username: resolveSecretRef(secretRef),
|
|
831
846
|
Password: resolveSecretPassword(secretRef),
|
|
@@ -561,9 +561,12 @@ describe('AuroraBuilder', () => {
|
|
|
561
561
|
expect(dbUrl['Fn::Sub'][0]).toMatch(
|
|
562
562
|
/^postgresql:\/\/\$\{Username\}:\$\{Password\}@\$\{Host\}:\$\{Port\}\/\$\{Database\}\?/
|
|
563
563
|
);
|
|
564
|
-
expect(dbUrl['Fn::Sub'][0]).toContain('connection_limit=
|
|
565
|
-
expect(dbUrl['Fn::Sub'][0]).toContain('pool_timeout=
|
|
564
|
+
expect(dbUrl['Fn::Sub'][0]).toContain('connection_limit=2');
|
|
565
|
+
expect(dbUrl['Fn::Sub'][0]).toContain('pool_timeout=20');
|
|
566
|
+
expect(dbUrl['Fn::Sub'][0]).toContain('connect_timeout=10');
|
|
567
|
+
expect(dbUrl['Fn::Sub'][0]).toContain('socket_timeout=60');
|
|
566
568
|
expect(dbUrl['Fn::Sub'][0]).toContain('statement_timeout%3D30000');
|
|
569
|
+
expect(dbUrl['Fn::Sub'][0]).toContain('lock_timeout%3D10000');
|
|
567
570
|
|
|
568
571
|
// The Username and Password should use Fn::Sub to resolve the secret Ref, not literal "[object Object]"
|
|
569
572
|
expect(dbUrl['Fn::Sub'][1].Username['Fn::Sub']).toBeDefined();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.
|
|
4
|
+
"version": "2.0.0--canary.5ff5209.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"frigg": "./frigg-cli/index.js"
|
|
7
7
|
},
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@babel/eslint-parser": "^7.18.9",
|
|
26
26
|
"@babel/parser": "^7.25.3",
|
|
27
27
|
"@babel/traverse": "^7.25.3",
|
|
28
|
-
"@friggframework/core": "2.0.0--canary.
|
|
29
|
-
"@friggframework/schemas": "2.0.0--canary.
|
|
30
|
-
"@friggframework/test": "2.0.0--canary.
|
|
28
|
+
"@friggframework/core": "2.0.0--canary.5ff5209.0",
|
|
29
|
+
"@friggframework/schemas": "2.0.0--canary.5ff5209.0",
|
|
30
|
+
"@friggframework/test": "2.0.0--canary.5ff5209.0",
|
|
31
31
|
"@hapi/boom": "^10.0.1",
|
|
32
32
|
"@inquirer/prompts": "^5.3.8",
|
|
33
33
|
"axios": "^1.7.2",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"validate-npm-package-name": "^5.0.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@friggframework/eslint-config": "2.0.0--canary.
|
|
59
|
-
"@friggframework/prettier-config": "2.0.0--canary.
|
|
58
|
+
"@friggframework/eslint-config": "2.0.0--canary.5ff5209.0",
|
|
59
|
+
"@friggframework/prettier-config": "2.0.0--canary.5ff5209.0",
|
|
60
60
|
"aws-sdk-client-mock": "^4.1.0",
|
|
61
61
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
62
62
|
"jest": "^30.1.3",
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"publishConfig": {
|
|
89
89
|
"access": "public"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "5ff5209460d3a908810fe53b5ff07eacccde963e"
|
|
92
92
|
}
|