Skip to content

Commit cdb480b

Browse files
committed
feat: add retry config customization in app init
1 parent a96729a commit cdb480b

13 files changed

+94
-16
lines changed

etc/firebase-admin.api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ export interface AppOptions {
7272
credential?: Credential;
7373
databaseAuthVariableOverride?: object | null;
7474
databaseURL?: string;
75+
disableRetry?: boolean;
7576
httpAgent?: Agent;
7677
projectId?: string;
78+
retryConfig?: RetryConfig;
7779
serviceAccountId?: string;
7880
storageBucket?: string;
7981
}
@@ -462,6 +464,15 @@ export namespace remoteConfig {
462464
export type Version = Version;
463465
}
464466

467+
// @public
468+
export interface RetryConfig {
469+
backOffFactor?: number;
470+
ioErrorCodes?: string[];
471+
maxDelayInMillis: number;
472+
maxRetries: number;
473+
statusCodes?: number[];
474+
}
475+
465476
// @public (undocumented)
466477
export const SDK_VERSION: string;
467478

etc/firebase-admin.app.api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ export interface AppOptions {
2222
credential?: Credential;
2323
databaseAuthVariableOverride?: object | null;
2424
databaseURL?: string;
25+
disableRetry?: boolean;
2526
httpAgent?: Agent;
2627
projectId?: string;
28+
retryConfig?: RetryConfig;
2729
serviceAccountId?: string;
2830
storageBucket?: string;
2931
}
@@ -73,6 +75,15 @@ export function initializeApp(options?: AppOptions, appName?: string): App;
7375
// @public
7476
export function refreshToken(refreshTokenPathOrObject: string | object, httpAgent?: Agent): Credential;
7577

78+
// @public
79+
export interface RetryConfig {
80+
backOffFactor?: number;
81+
ioErrorCodes?: string[];
82+
maxDelayInMillis: number;
83+
maxRetries: number;
84+
statusCodes?: number[];
85+
}
86+
7687
// @public (undocumented)
7788
export const SDK_VERSION: string;
7889

src/app/core.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import { Agent } from 'http';
1919

2020
import { Credential } from './credential';
21+
import { RetryConfig } from '.'
2122

2223
/**
2324
* Available options to pass to {@link firebase-admin.app#initializeApp}.
@@ -83,6 +84,16 @@ export interface AppOptions {
8384
* specifying an HTTP Agent in the corresponding factory methods.
8485
*/
8586
httpAgent?: Agent;
87+
88+
/**
89+
* The retry configuration that will be used in HttpClient for API Requests.
90+
*/
91+
retryConfig?: RetryConfig;
92+
93+
/**
94+
* Completely disable the retry strategy in HttpClient.
95+
*/
96+
disableRetry?: boolean;
8697
}
8798

8899
/**

src/app/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ export { initializeApp, getApp, getApps, deleteApp } from './lifecycle';
2828

2929
export { Credential, ServiceAccount, GoogleOAuthAccessToken } from './credential';
3030
export { applicationDefault, cert, refreshToken } from './credential-factory';
31+
export { RetryConfig } from '../utils/api-request'
3132

3233
export const SDK_VERSION = getSdkVersion();

src/auth/auth-api-request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const FIREBASE_AUTH_HEADER = {
4848
'X-Client-Version': `Node/Admin/${utils.getSdkVersion()}`,
4949
};
5050
/** Firebase Auth request timeout duration in milliseconds. */
51-
const FIREBASE_AUTH_TIMEOUT = 25000;
51+
const FIREBASE_AUTH_TIMEOUT = parseInt(process.env.FIREBASE_AUTH_TIMEOUT || '25000', 10);
5252

5353

5454
/** List of reserved claims which cannot be provided when creating a custom token. */

src/firebase-namespace-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export { projectManagement } from './project-management/project-management-names
9191
export { remoteConfig } from './remote-config/remote-config-namespace';
9292
export { securityRules } from './security-rules/security-rules-namespace';
9393
export { storage } from './storage/storage-namespace';
94+
export { RetryConfig } from './utils/api-request'
9495

9596
// Declare other top-level members of the admin namespace below. Unfortunately, there's no
9697
// compile-time mechanism to ensure that the FirebaseNamespace class actually provides these

src/messaging/batch-request-internal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { FirebaseAppError, AppErrorCodes } from '../utils/error';
2121

2222
const PART_BOUNDARY = '__END_OF_PART__';
23-
const TEN_SECONDS_IN_MILLIS = 10000;
23+
const FIREBASE_MESSAGING_BATCH_TIMEOUT = parseInt(process.env.FIREBASE_MESSAGING_BATCH_TIMEOUT || '10000', 10);
2424

2525
/**
2626
* Represents a request that can be sent as part of an HTTP batch request.
@@ -72,7 +72,7 @@ export class BatchRequestClient {
7272
url: this.batchUrl,
7373
data: this.getMultipartPayload(requests),
7474
headers: Object.assign({}, this.commonHeaders, requestHeaders),
75-
timeout: TEN_SECONDS_IN_MILLIS,
75+
timeout: FIREBASE_MESSAGING_BATCH_TIMEOUT,
7676
};
7777
return this.httpClient.send(request).then((response) => {
7878
if (!response.multipart) {

src/messaging/messaging-api-request-internal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { SendResponse, BatchResponse } from './messaging-api';
2727

2828

2929
// FCM backend constants
30-
const FIREBASE_MESSAGING_TIMEOUT = 10000;
30+
const FIREBASE_MESSAGING_TIMEOUT = parseInt(process.env.FIREBASE_MESSAGING_TIMEOUT || '10000', 10);
3131
const FIREBASE_MESSAGING_BATCH_URL = 'https://fcm.googleapis.com/batch';
3232
const FIREBASE_MESSAGING_HTTP_METHOD: HttpMethod = 'POST';
3333
const FIREBASE_MESSAGING_HEADERS = {

src/project-management/project-management-api-request-internal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const PROJECT_MANAGEMENT_HEADERS = {
3636
'X-Client-Version': `Node/Admin/${getSdkVersion()}`,
3737
};
3838
/** Project management request timeout duration in milliseconds. */
39-
const PROJECT_MANAGEMENT_TIMEOUT_MILLIS = 10000;
39+
const FIREBASE_PROJECT_MANAGEMENT_TIMEOUT = parseInt(process.env.FIREBASE_PROJECT_MANAGEMENT_TIMEOUT || '10000', 10);
4040

4141
const LIST_APPS_MAX_PAGE_SIZE = 100;
4242

@@ -315,7 +315,7 @@ export class ProjectManagementRequestHandler {
315315
url: `${baseUrlToUse}${path}`,
316316
headers: PROJECT_MANAGEMENT_HEADERS,
317317
data: requestData,
318-
timeout: PROJECT_MANAGEMENT_TIMEOUT_MILLIS,
318+
timeout: FIREBASE_PROJECT_MANAGEMENT_TIMEOUT,
319319
};
320320

321321
return this.httpClient.send(request)

src/utils/api-request.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,13 @@ function validateRetryConfig(retry: RetryConfig): void {
243243

244244
export class HttpClient {
245245

246-
constructor(private readonly retry: RetryConfig | null = defaultRetryConfig()) {
247-
if (this.retry) {
246+
constructor(
247+
private readonly retry: RetryConfig | null = null,
248+
private readonly disableRetry: boolean = false
249+
) {
250+
if (!this.disableRetry && !this.retry) {
251+
this.retry = defaultRetryConfig();
252+
} else if (!this.disableRetry && this.retry) {
248253
validateRetryConfig(this.retry);
249254
}
250255
}
@@ -345,7 +350,7 @@ export class HttpClient {
345350
}
346351

347352
private isRetryEligible(retryAttempts: number, err: LowLevelError): boolean {
348-
if (!this.retry) {
353+
if (this.disableRetry || !this.retry) {
349354
return false;
350355
}
351356

@@ -811,7 +816,7 @@ class HttpRequestConfigImpl implements HttpRequestConfig {
811816

812817
export class AuthorizedHttpClient extends HttpClient {
813818
constructor(private readonly app: FirebaseApp) {
814-
super();
819+
super(app.options.retryConfig, app.options.disableRetry);
815820
}
816821

817822
public send(request: HttpRequestConfig): Promise<HttpResponse> {

0 commit comments

Comments
 (0)