@@ -130,17 +130,22 @@ export class Fabricator {
130130 } ;
131131
132132 const upserts : Array < Promise < void > > = [ ] ;
133- const scraper = new SourceTokenScraper ( ) ;
133+ const scraperV1 = new SourceTokenScraper ( ) ;
134+ const scraperV2 = new SourceTokenScraper ( ) ;
134135 for ( const endpoint of changes . endpointsToCreate ) {
135136 this . logOpStart ( "creating" , endpoint ) ;
136- upserts . push ( handle ( "create" , endpoint , ( ) => this . createEndpoint ( endpoint , scraper ) ) ) ;
137+ upserts . push (
138+ handle ( "create" , endpoint , ( ) => this . createEndpoint ( endpoint , scraperV1 , scraperV2 ) )
139+ ) ;
137140 }
138141 for ( const endpoint of changes . endpointsToSkip ) {
139142 utils . logSuccess ( this . getLogSuccessMessage ( "skip" , endpoint ) ) ;
140143 }
141144 for ( const update of changes . endpointsToUpdate ) {
142145 this . logOpStart ( "updating" , update . endpoint ) ;
143- upserts . push ( handle ( "update" , update . endpoint , ( ) => this . updateEndpoint ( update , scraper ) ) ) ;
146+ upserts . push (
147+ handle ( "update" , update . endpoint , ( ) => this . updateEndpoint ( update , scraperV1 , scraperV2 ) )
148+ ) ;
144149 }
145150 await utils . allSettled ( upserts ) ;
146151
@@ -167,31 +172,39 @@ export class Fabricator {
167172 return deployResults ;
168173 }
169174
170- async createEndpoint ( endpoint : backend . Endpoint , scraper : SourceTokenScraper ) : Promise < void > {
175+ async createEndpoint (
176+ endpoint : backend . Endpoint ,
177+ scraperV1 : SourceTokenScraper ,
178+ scraperV2 : SourceTokenScraper
179+ ) : Promise < void > {
171180 endpoint . labels = { ...endpoint . labels , ...deploymentTool . labels ( ) } ;
172181 if ( endpoint . platform === "gcfv1" ) {
173- await this . createV1Function ( endpoint , scraper ) ;
182+ await this . createV1Function ( endpoint , scraperV1 ) ;
174183 } else if ( endpoint . platform === "gcfv2" ) {
175- await this . createV2Function ( endpoint ) ;
184+ await this . createV2Function ( endpoint , scraperV2 ) ;
176185 } else {
177186 assertExhaustive ( endpoint . platform ) ;
178187 }
179188
180189 await this . setTrigger ( endpoint ) ;
181190 }
182191
183- async updateEndpoint ( update : planner . EndpointUpdate , scraper : SourceTokenScraper ) : Promise < void > {
192+ async updateEndpoint (
193+ update : planner . EndpointUpdate ,
194+ scraperV1 : SourceTokenScraper ,
195+ scraperV2 : SourceTokenScraper
196+ ) : Promise < void > {
184197 update . endpoint . labels = { ...update . endpoint . labels , ...deploymentTool . labels ( ) } ;
185198 if ( update . deleteAndRecreate ) {
186199 await this . deleteEndpoint ( update . deleteAndRecreate ) ;
187- await this . createEndpoint ( update . endpoint , scraper ) ;
200+ await this . createEndpoint ( update . endpoint , scraperV1 , scraperV2 ) ;
188201 return ;
189202 }
190203
191204 if ( update . endpoint . platform === "gcfv1" ) {
192- await this . updateV1Function ( update . endpoint , scraper ) ;
205+ await this . updateV1Function ( update . endpoint , scraperV1 ) ;
193206 } else if ( update . endpoint . platform === "gcfv2" ) {
194- await this . updateV2Function ( update . endpoint ) ;
207+ await this . updateV2Function ( update . endpoint , scraperV2 ) ;
195208 } else {
196209 assertExhaustive ( update . endpoint . platform ) ;
197210 }
@@ -276,7 +289,7 @@ export class Fabricator {
276289 }
277290 }
278291
279- async createV2Function ( endpoint : backend . Endpoint ) : Promise < void > {
292+ async createV2Function ( endpoint : backend . Endpoint , scraper : SourceTokenScraper ) : Promise < void > {
280293 const storageSource = this . sources [ endpoint . codebase ! ] ?. storage ;
281294 if ( ! storageSource ) {
282295 logger . debug ( "Precondition failed. Cannot create a GCFv2 function without storage" ) ;
@@ -351,14 +364,19 @@ export class Fabricator {
351364 while ( ! resultFunction ) {
352365 resultFunction = await this . functionExecutor
353366 . run ( async ( ) => {
367+ apiFunction . buildConfig . sourceToken = await scraper . getToken ( ) ;
354368 const op : { name : string } = await gcfV2 . createFunction ( apiFunction ) ;
355369 return await poller . pollOperation < gcfV2 . OutputCloudFunction > ( {
356370 ...gcfV2PollerOptions ,
357371 pollerName : `create-${ endpoint . codebase } -${ endpoint . region } -${ endpoint . id } ` ,
358372 operationResourceName : op . name ,
373+ onPoll : scraper . poller ,
359374 } ) ;
360375 } )
361376 . catch ( async ( err : any ) => {
377+ // Abort waiting on source token so other concurrent calls don't get stuck
378+ scraper . abort ( ) ;
379+
362380 // If the createFunction call returns RPC error code RESOURCE_EXHAUSTED (8),
363381 // we have exhausted the underlying Cloud Run API quota. To retry, we need to
364382 // first delete the GCF function resource, then call createFunction again.
@@ -463,7 +481,7 @@ export class Fabricator {
463481 }
464482 }
465483
466- async updateV2Function ( endpoint : backend . Endpoint ) : Promise < void > {
484+ async updateV2Function ( endpoint : backend . Endpoint , scraper : SourceTokenScraper ) : Promise < void > {
467485 const storageSource = this . sources [ endpoint . codebase ! ] ?. storage ;
468486 if ( ! storageSource ) {
469487 logger . debug ( "Precondition failed. Cannot update a GCFv2 function without storage" ) ;
@@ -482,16 +500,22 @@ export class Fabricator {
482500 const resultFunction = await this . functionExecutor
483501 . run (
484502 async ( ) => {
503+ apiFunction . buildConfig . sourceToken = await scraper . getToken ( ) ;
485504 const op : { name : string } = await gcfV2 . updateFunction ( apiFunction ) ;
486505 return await poller . pollOperation < gcfV2 . OutputCloudFunction > ( {
487506 ...gcfV2PollerOptions ,
488507 pollerName : `update-${ endpoint . codebase } -${ endpoint . region } -${ endpoint . id } ` ,
489508 operationResourceName : op . name ,
509+ onPoll : scraper . poller ,
490510 } ) ;
491511 } ,
492512 { retryCodes : [ ...DEFAULT_RETRY_CODES , CLOUD_RUN_RESOURCE_EXHAUSTED_CODE ] }
493513 )
494- . catch ( rethrowAs < gcfV2 . OutputCloudFunction > ( endpoint , "update" ) ) ;
514+ . catch ( ( err : any ) => {
515+ scraper . abort ( ) ;
516+ logger . error ( ( err as Error ) . message ) ;
517+ throw new reporter . DeploymentError ( endpoint , "update" , err ) ;
518+ } ) ;
495519
496520 endpoint . uri = resultFunction . serviceConfig ?. uri ;
497521 const serviceName = resultFunction . serviceConfig ?. service ;
0 commit comments