@@ -28,16 +28,12 @@ import * as Pumpify from 'pumpify';
2828import { Duplex , PassThrough , Readable } from 'stream' ;
2929import * as streamEvents from 'stream-events' ;
3030import retry = require( 'async-retry' ) ;
31+ import { RetryOptions , PreconditionOptions } from '../storage' ;
3132
3233const NOT_FOUND_STATUS_CODE = 404 ;
3334const TERMINATED_UPLOAD_STATUS_CODE = 410 ;
3435const RESUMABLE_INCOMPLETE_STATUS_CODE = 308 ;
35- const RETRY_LIMIT = 5 ;
3636const DEFAULT_API_ENDPOINT_REGEX = / .* \. g o o g l e a p i s \. c o m / ;
37- const MAX_RETRY_DELAY = 64 ;
38- const RETRY_DELAY_MULTIPLIER = 2 ;
39- const MAX_TOTAL_RETRY_TIMEOUT = 600 ;
40- const AUTO_RETRY_VALUE = true ;
4137
4238export const PROTOCOL_REGEX = / ^ ( \w * ) : \/ \/ / ;
4339
@@ -60,12 +56,8 @@ export type PredefinedAcl =
6056 | 'projectPrivate'
6157 | 'publicRead' ;
6258
63- export interface QueryParameters {
59+ export interface QueryParameters extends PreconditionOptions {
6460 contentEncoding ?: string ;
65- ifGenerationMatch ?: number ;
66- ifGenerationNotMatch ?: number ;
67- ifMetagenerationMatch ?: number ;
68- ifMetagenerationNotMatch ?: number ;
6961 kmsKeyName ?: string ;
7062 predefinedAcl ?: PredefinedAcl ;
7163 projection ?: 'full' | 'noAcl' ;
@@ -207,7 +199,7 @@ export interface UploadConfig {
207199 /**
208200 * Configuration options for retrying retryable errors.
209201 */
210- retryOptions ? : RetryOptions ;
202+ retryOptions : RetryOptions ;
211203}
212204
213205export interface ConfigMetadata {
@@ -225,15 +217,6 @@ export interface ConfigMetadata {
225217 contentType ?: string ;
226218}
227219
228- export interface RetryOptions {
229- retryDelayMultiplier ?: number ;
230- totalTimeout ?: number ;
231- maxRetryDelay ?: number ;
232- autoRetry ?: boolean ;
233- maxRetries ?: number ;
234- retryableErrorFn ?: ( err : ApiError ) => boolean ;
235- }
236-
237220export interface GoogleInnerError {
238221 reason ?: string ;
239222}
@@ -279,12 +262,8 @@ export class Upload extends Pumpify {
279262 numBytesWritten = 0 ;
280263 numRetries = 0 ;
281264 contentLength : number | '*' ;
282- retryLimit : number = RETRY_LIMIT ;
283- maxRetryDelay : number = MAX_RETRY_DELAY ;
284- retryDelayMultiplier : number = RETRY_DELAY_MULTIPLIER ;
285- maxRetryTotalTimeout : number = MAX_TOTAL_RETRY_TIMEOUT ;
265+ retryOptions : RetryOptions ;
286266 timeOfFirstRequest : number ;
287- retryableErrorFn ?: ( err : ApiError ) => boolean ;
288267 private upstreamChunkBuffer : Buffer = Buffer . alloc ( 0 ) ;
289268 private chunkBufferEncoding ?: BufferEncoding = undefined ;
290269 private numChunksReadInRequest = 0 ;
@@ -340,6 +319,7 @@ export class Upload extends Pumpify {
340319 this . params = cfg . params || { } ;
341320 this . userProject = cfg . userProject ;
342321 this . chunkSize = cfg . chunkSize ;
322+ this . retryOptions = cfg . retryOptions ;
343323
344324 if ( cfg . key ) {
345325 /**
@@ -363,32 +343,16 @@ export class Upload extends Pumpify {
363343 configPath,
364344 } ) ;
365345
366- const autoRetry = cfg ? .retryOptions ? .autoRetry || AUTO_RETRY_VALUE ;
346+ const autoRetry = cfg . retryOptions . autoRetry ;
367347 this . uriProvidedManually = ! ! cfg . uri ;
368348 this . uri = cfg . uri || this . get ( 'uri' ) ;
369349 this . numBytesWritten = 0 ;
370350 this . numRetries = 0 ; //counter for number of retries currently executed
371-
372- if ( autoRetry && cfg ?. retryOptions ?. maxRetries !== undefined ) {
373- this . retryLimit = cfg . retryOptions . maxRetries ;
374- } else if ( ! autoRetry ) {
375- this . retryLimit = 0 ;
376- }
377-
378- if ( cfg ?. retryOptions ?. maxRetryDelay !== undefined ) {
379- this . maxRetryDelay = cfg . retryOptions . maxRetryDelay ;
380- }
381-
382- if ( cfg ?. retryOptions ?. retryDelayMultiplier !== undefined ) {
383- this . retryDelayMultiplier = cfg . retryOptions . retryDelayMultiplier ;
384- }
385-
386- if ( cfg ?. retryOptions ?. totalTimeout !== undefined ) {
387- this . maxRetryTotalTimeout = cfg . retryOptions . totalTimeout ;
351+ if ( ! autoRetry ) {
352+ cfg . retryOptions . maxRetries = 0 ;
388353 }
389354
390355 this . timeOfFirstRequest = Date . now ( ) ;
391- this . retryableErrorFn = cfg ?. retryOptions ?. retryableErrorFn ;
392356
393357 const contentLength = cfg . metadata
394358 ? Number ( cfg . metadata . contentLength )
@@ -646,9 +610,8 @@ export class Upload extends Pumpify {
646610 ] ,
647611 } ;
648612 if (
649- this . retryLimit > 0 &&
650- this . retryableErrorFn &&
651- this . retryableErrorFn ! ( apiError as ApiError )
613+ this . retryOptions . maxRetries ! > 0 &&
614+ this . retryOptions . retryableErrorFn ! ( apiError as ApiError )
652615 ) {
653616 throw e ;
654617 } else {
@@ -657,10 +620,10 @@ export class Upload extends Pumpify {
657620 }
658621 } ,
659622 {
660- retries : this . retryLimit ,
661- factor : this . retryDelayMultiplier ,
662- maxTimeout : this . maxRetryDelay ! * 1000 , //convert to milliseconds
663- maxRetryTime : this . maxRetryTotalTimeout ! * 1000 , //convert to milliseconds
623+ retries : this . retryOptions . maxRetries ,
624+ factor : this . retryOptions . retryDelayMultiplier ,
625+ maxTimeout : this . retryOptions . maxRetryDelay ! * 1000 , //convert to milliseconds
626+ maxRetryTime : this . retryOptions . totalTimeout ! * 1000 , //convert to milliseconds
664627 }
665628 ) ;
666629
@@ -1055,14 +1018,11 @@ export class Upload extends Pumpify {
10551018 */
10561019 private onResponse ( resp : GaxiosResponse ) {
10571020 if (
1058- ( this . retryableErrorFn &&
1059- this . retryableErrorFn ( {
1060- code : resp . status ,
1061- message : resp . statusText ,
1062- name : resp . statusText ,
1063- } ) ) ||
1064- resp . status === NOT_FOUND_STATUS_CODE ||
1065- this . isServerErrorResponse ( resp . status )
1021+ this . retryOptions . retryableErrorFn ! ( {
1022+ code : resp . status ,
1023+ message : resp . statusText ,
1024+ name : resp . statusText ,
1025+ } )
10661026 ) {
10671027 this . attemptDelayedRetry ( resp ) ;
10681028 return false ;
@@ -1076,7 +1036,7 @@ export class Upload extends Pumpify {
10761036 * @param resp GaxiosResponse object from previous attempt
10771037 */
10781038 private attemptDelayedRetry ( resp : GaxiosResponse ) {
1079- if ( this . numRetries < this . retryLimit ) {
1039+ if ( this . numRetries < this . retryOptions . maxRetries ! ) {
10801040 if (
10811041 resp . status === NOT_FOUND_STATUS_CODE &&
10821042 this . numChunksReadInRequest === 0
@@ -1120,10 +1080,13 @@ export class Upload extends Pumpify {
11201080 private getRetryDelay ( ) : number {
11211081 const randomMs = Math . round ( Math . random ( ) * 1000 ) ;
11221082 const waitTime =
1123- Math . pow ( this . retryDelayMultiplier , this . numRetries ) * 1000 + randomMs ;
1083+ Math . pow ( this . retryOptions . retryDelayMultiplier ! , this . numRetries ) *
1084+ 1000 +
1085+ randomMs ;
11241086 const maxAllowableDelayMs =
1125- this . maxRetryTotalTimeout * 1000 - ( Date . now ( ) - this . timeOfFirstRequest ) ;
1126- const maxRetryDelayMs = this . maxRetryDelay * 1000 ;
1087+ this . retryOptions . totalTimeout ! * 1000 -
1088+ ( Date . now ( ) - this . timeOfFirstRequest ) ;
1089+ const maxRetryDelayMs = this . retryOptions . maxRetryDelay ! * 1000 ;
11271090
11281091 return Math . min ( waitTime , maxRetryDelayMs , maxAllowableDelayMs ) ;
11291092 }
@@ -1147,16 +1110,6 @@ export class Upload extends Pumpify {
11471110 public isSuccessfulResponse ( status : number ) : boolean {
11481111 return status >= 200 && status < 300 ;
11491112 }
1150-
1151- /**
1152- * Check if a given status code is 5xx
1153- *
1154- * @param status The status code to check
1155- * @returns if the status is 5xx
1156- */
1157- public isServerErrorResponse ( status : number ) : boolean {
1158- return status >= 500 && status < 600 ;
1159- }
11601113}
11611114
11621115export function upload ( cfg : UploadConfig ) {
0 commit comments