88 DeleteFunctionCommand ,
99 DeleteLayerVersionCommand ,
1010 GetFunctionCommand ,
11+ GetFunctionCommandOutput ,
1112 InvokeCommand ,
1213 type InvokeCommandInput ,
1314 Lambda ,
@@ -17,7 +18,9 @@ import {
1718 LogType ,
1819 PublishLayerVersionCommand ,
1920 ResourceNotFoundException ,
21+ UpdateFunctionConfigurationCommand ,
2022 waitUntilFunctionActiveV2 ,
23+ waitUntilFunctionUpdatedV2 ,
2124} from '@aws-sdk/client-lambda' ;
2225import { PutObjectCommand , S3Client } from '@aws-sdk/client-s3' ;
2326import { AssumeRoleCommand , STSClient } from '@aws-sdk/client-sts' ;
@@ -233,6 +236,16 @@ export class LambdaDriver implements LogicFunctionDriver {
233236 ) ;
234237 }
235238
239+ private async waitFunctionUpdated (
240+ functionName : string ,
241+ maxWaitTime : number = UPDATE_FUNCTION_DURATION_TIMEOUT_IN_SECONDS ,
242+ ) {
243+ await waitUntilFunctionUpdatedV2 (
244+ { client : await this . getLambdaClient ( ) , maxWaitTime } ,
245+ { FunctionName : functionName } ,
246+ ) ;
247+ }
248+
236249 private getDepsLayerName ( flatApplication : FlatApplication ) : string {
237250 const checksum = flatApplication . yarnLockChecksum ?? 'default' ;
238251
@@ -858,26 +871,18 @@ export class LambdaDriver implements LogicFunctionDriver {
858871 } while ( isDefined ( marker ) ) ;
859872 }
860873
861- private async isAlreadyBuilt ( {
862- flatLogicFunction ,
874+ private hasExpectedLayers ( {
875+ lambdaExecutor ,
863876 flatApplication,
864877 applicationUniversalIdentifier,
865878 } : {
866- flatLogicFunction : FlatLogicFunction ;
879+ lambdaExecutor : GetFunctionCommandOutput ;
867880 flatApplication : FlatApplication ;
868881 applicationUniversalIdentifier : string ;
869- } ) {
870- const lambdaExecutor = await this . getLambdaExecutor ( flatLogicFunction ) ;
871-
872- if ( ! isDefined ( lambdaExecutor ) ) {
873- return false ;
874- }
875-
882+ } ) : boolean {
876883 const layers = lambdaExecutor . Configuration ?. Layers ;
877884
878885 if ( ! isDefined ( layers ) || layers . length !== 2 ) {
879- await this . delete ( flatLogicFunction ) ;
880-
881886 return false ;
882887 }
883888
@@ -887,20 +892,34 @@ export class LambdaDriver implements LogicFunctionDriver {
887892 applicationUniversalIdentifier,
888893 } ) ;
889894
890- const hasExpectedLayers =
895+ return (
891896 layers . some ( ( layer ) => layer . Arn ?. includes ( depsLayerName ) ) &&
892- layers . some ( ( layer ) => layer . Arn ?. includes ( sdkLayerName ) ) ;
893-
894- if ( hasExpectedLayers ) {
895- return true ;
896- }
897+ layers . some ( ( layer ) => layer . Arn ?. includes ( sdkLayerName ) )
898+ ) ;
899+ }
897900
898- await this . delete ( flatLogicFunction ) ;
901+ private async updateLambdaExecutorConfiguration ( {
902+ flatLogicFunction,
903+ depsLayerArn,
904+ sdkLayerArn,
905+ } : {
906+ flatLogicFunction : FlatLogicFunction ;
907+ depsLayerArn : string ;
908+ sdkLayerArn : string ;
909+ } ) {
910+ const lambdaClient = await this . getLambdaClient ( ) ;
899911
900- return false ;
912+ await lambdaClient . send (
913+ new UpdateFunctionConfigurationCommand ( {
914+ FunctionName : flatLogicFunction . id ,
915+ Layers : [ depsLayerArn , sdkLayerArn ] ,
916+ Runtime : flatLogicFunction . runtime ,
917+ Timeout : 900 ,
918+ } ) ,
919+ ) ;
901920 }
902921
903- private async build ( {
922+ private async buildLambdaExecutor ( {
904923 flatLogicFunction,
905924 flatApplication,
906925 applicationUniversalIdentifier,
@@ -915,7 +934,9 @@ export class LambdaDriver implements LogicFunctionDriver {
915934 applicationUniversalIdentifier,
916935 } ;
917936
918- if ( await this . canSkipBuild ( buildArgs ) ) {
937+ const { canSkip } = await this . checkLambdaExecutorBuildStatus ( buildArgs ) ;
938+
939+ if ( canSkip ) {
919940 return ;
920941 }
921942
@@ -926,11 +947,14 @@ export class LambdaDriver implements LogicFunctionDriver {
926947 await this . cacheLockService . withLock (
927948 async ( ) => {
928949 // Need to check again inside the lock in case lock was not acquired immediately.
929- if ( await this . canSkipBuild ( buildArgs ) ) {
950+ const { canSkip, lambdaExecutor } =
951+ await this . checkLambdaExecutorBuildStatus ( buildArgs ) ;
952+
953+ if ( canSkip ) {
930954 return ;
931955 }
932956
933- await this . createLambdaExecutor ( buildArgs ) ;
957+ await this . ensureLambdaExecutor ( { ... buildArgs , lambdaExecutor } ) ;
934958 } ,
935959 `lambda-build:${ flatLogicFunction . id } ` ,
936960 {
@@ -941,36 +965,43 @@ export class LambdaDriver implements LogicFunctionDriver {
941965 ) ;
942966 }
943967
944- private async canSkipBuild ( {
968+ private async checkLambdaExecutorBuildStatus ( {
945969 flatLogicFunction,
946970 flatApplication,
947971 applicationUniversalIdentifier,
948972 } : {
949973 flatLogicFunction : FlatLogicFunction ;
950974 flatApplication : FlatApplication ;
951975 applicationUniversalIdentifier : string ;
952- } ) {
953- return (
976+ } ) : Promise < {
977+ canSkip : boolean ;
978+ lambdaExecutor : GetFunctionCommandOutput | undefined ;
979+ } > {
980+ const lambdaExecutor = await this . getLambdaExecutor ( flatLogicFunction ) ;
981+
982+ const canSkip =
983+ isDefined ( lambdaExecutor ) &&
954984 ! flatApplication . isSdkLayerStale &&
955- ( await this . isAlreadyBuilt ( {
956- flatLogicFunction ,
985+ this . hasExpectedLayers ( {
986+ lambdaExecutor ,
957987 flatApplication,
958988 applicationUniversalIdentifier,
959- } ) )
960- ) ;
989+ } ) ;
990+
991+ return { canSkip, lambdaExecutor } ;
961992 }
962993
963- private async createLambdaExecutor ( {
994+ private async ensureLambdaExecutor ( {
964995 flatLogicFunction,
965996 flatApplication,
966997 applicationUniversalIdentifier,
998+ lambdaExecutor,
967999 } : {
9681000 flatLogicFunction : FlatLogicFunction ;
9691001 flatApplication : FlatApplication ;
9701002 applicationUniversalIdentifier : string ;
1003+ lambdaExecutor : GetFunctionCommandOutput | undefined ;
9711004 } ) {
972- await this . delete ( flatLogicFunction ) ;
973-
9741005 const depsLayerArn = await this . getLayerArn ( {
9751006 flatApplication,
9761007 applicationUniversalIdentifier,
@@ -981,6 +1012,34 @@ export class LambdaDriver implements LogicFunctionDriver {
9811012 applicationUniversalIdentifier,
9821013 } ) ;
9831014
1015+ if ( ! isDefined ( lambdaExecutor ) ) {
1016+ await this . createLambdaExecutor ( {
1017+ flatLogicFunction,
1018+ depsLayerArn,
1019+ sdkLayerArn,
1020+ } ) ;
1021+ await this . waitFunctionActive ( flatLogicFunction . id ) ;
1022+
1023+ return ;
1024+ }
1025+
1026+ await this . updateLambdaExecutorConfiguration ( {
1027+ flatLogicFunction,
1028+ depsLayerArn,
1029+ sdkLayerArn,
1030+ } ) ;
1031+ await this . waitFunctionUpdated ( flatLogicFunction . id ) ;
1032+ }
1033+
1034+ private async createLambdaExecutor ( {
1035+ flatLogicFunction,
1036+ depsLayerArn,
1037+ sdkLayerArn,
1038+ } : {
1039+ flatLogicFunction : FlatLogicFunction ;
1040+ depsLayerArn : string ;
1041+ sdkLayerArn : string ;
1042+ } ) {
9841043 const temporaryDirManager = new TemporaryDirManager ( ) ;
9851044
9861045 const { sourceTemporaryDir, lambdaZipPath } =
@@ -1006,9 +1065,9 @@ export class LambdaDriver implements LogicFunctionDriver {
10061065 EphemeralStorage : { Size : LAMBDA_EPHEMERAL_STORAGE_MB } ,
10071066 } ;
10081067
1009- const command = new CreateFunctionCommand ( params ) ;
1068+ const lambdaClient = await this . getLambdaClient ( ) ;
10101069
1011- await ( await this . getLambdaClient ( ) ) . send ( command ) ;
1070+ await lambdaClient . send ( new CreateFunctionCommand ( params ) ) ;
10121071 } finally {
10131072 await temporaryDirManager . clean ( ) ;
10141073 }
@@ -1037,14 +1096,12 @@ export class LambdaDriver implements LogicFunctionDriver {
10371096 env,
10381097 timeoutMs = 900_000 ,
10391098 } : LogicFunctionExecuteParams ) : Promise < LogicFunctionExecuteResult > {
1040- await this . build ( {
1099+ await this . buildLambdaExecutor ( {
10411100 flatLogicFunction,
10421101 flatApplication,
10431102 applicationUniversalIdentifier,
10441103 } ) ;
10451104
1046- await this . waitFunctionActive ( flatLogicFunction . id ) ;
1047-
10481105 const startTime = Date . now ( ) ;
10491106
10501107 const compiledCode = await this . logicFunctionResourceService . getBuiltCode ( {
0 commit comments