Skip to content

Commit fc9687f

Browse files
feat: deferred client initialization (#321)
This PR includes changes from googleapis/gapic-generator-typescript#317 that will move the asynchronous initialization and authentication from the client constructor to an `initialize()` method. This method will be automatically called when the first RPC call is performed. The client library usage has not changed, there is no need to update any code. If you want to make sure the client is authenticated _before_ the first RPC call, you can do ```js await client.initialize(); ``` manually before calling any client method.
1 parent 1520797 commit fc9687f

File tree

3 files changed

+153
-34
lines changed

3 files changed

+153
-34
lines changed

packages/google-cloud-bigquery-datatransfer/src/v1/data_transfer_service_client.ts

+77-30
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,13 @@ export class DataTransferServiceClient {
4747
private _innerApiCalls: {[name: string]: Function};
4848
private _pathTemplates: {[name: string]: gax.PathTemplate};
4949
private _terminated = false;
50+
private _opts: ClientOptions;
51+
private _gaxModule: typeof gax | typeof gax.fallback;
52+
private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient;
53+
private _protos: {};
54+
private _defaults: {[method: string]: gax.CallSettings};
5055
auth: gax.GoogleAuth;
51-
dataTransferServiceStub: Promise<{[name: string]: Function}>;
56+
dataTransferServiceStub?: Promise<{[name: string]: Function}>;
5257

5358
/**
5459
* Construct an instance of DataTransferServiceClient.
@@ -72,8 +77,6 @@ export class DataTransferServiceClient {
7277
* app is running in an environment which supports
7378
* {@link https://developers.google.com/identity/protocols/application-default-credentials Application Default Credentials},
7479
* your project ID will be detected automatically.
75-
* @param {function} [options.promise] - Custom promise module to use instead
76-
* of native Promises.
7780
* @param {string} [options.apiEndpoint] - The domain name of the
7881
* API remote host.
7982
*/
@@ -103,25 +106,28 @@ export class DataTransferServiceClient {
103106
// If we are in browser, we are already using fallback because of the
104107
// "browser" field in package.json.
105108
// But if we were explicitly requested to use fallback, let's do it now.
106-
const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax;
109+
this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax;
107110

108111
// Create a `gaxGrpc` object, with any grpc-specific options
109112
// sent to the client.
110113
opts.scopes = (this.constructor as typeof DataTransferServiceClient).scopes;
111-
const gaxGrpc = new gaxModule.GrpcClient(opts);
114+
this._gaxGrpc = new this._gaxModule.GrpcClient(opts);
115+
116+
// Save options to use in initialize() method.
117+
this._opts = opts;
112118

113119
// Save the auth object to the client, for use by other methods.
114-
this.auth = gaxGrpc.auth as gax.GoogleAuth;
120+
this.auth = this._gaxGrpc.auth as gax.GoogleAuth;
115121

116122
// Determine the client header string.
117-
const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`];
123+
const clientHeader = [`gax/${this._gaxModule.version}`, `gapic/${version}`];
118124
if (typeof process !== 'undefined' && 'versions' in process) {
119125
clientHeader.push(`gl-node/${process.versions.node}`);
120126
} else {
121-
clientHeader.push(`gl-web/${gaxModule.version}`);
127+
clientHeader.push(`gl-web/${this._gaxModule.version}`);
122128
}
123129
if (!opts.fallback) {
124-
clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`);
130+
clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`);
125131
}
126132
if (opts.libName && opts.libVersion) {
127133
clientHeader.push(`${opts.libName}/${opts.libVersion}`);
@@ -137,31 +143,33 @@ export class DataTransferServiceClient {
137143
'protos',
138144
'protos.json'
139145
);
140-
const protos = gaxGrpc.loadProto(
146+
this._protos = this._gaxGrpc.loadProto(
141147
opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath
142148
);
143149

144150
// This API contains "path templates"; forward-slash-separated
145151
// identifiers to uniquely identify resources within the API.
146152
// Create useful helper objects for these.
147153
this._pathTemplates = {
148-
projectPathTemplate: new gaxModule.PathTemplate('projects/{project}'),
149-
projectDataSourcePathTemplate: new gaxModule.PathTemplate(
154+
projectPathTemplate: new this._gaxModule.PathTemplate(
155+
'projects/{project}'
156+
),
157+
projectDataSourcePathTemplate: new this._gaxModule.PathTemplate(
150158
'projects/{project}/dataSources/{data_source}'
151159
),
152-
projectLocationDataSourcePathTemplate: new gaxModule.PathTemplate(
160+
projectLocationDataSourcePathTemplate: new this._gaxModule.PathTemplate(
153161
'projects/{project}/locations/{location}/dataSources/{data_source}'
154162
),
155-
projectLocationTransferConfigPathTemplate: new gaxModule.PathTemplate(
163+
projectLocationTransferConfigPathTemplate: new this._gaxModule.PathTemplate(
156164
'projects/{project}/locations/{location}/transferConfigs/{transfer_config}'
157165
),
158-
projectLocationTransferConfigRunPathTemplate: new gaxModule.PathTemplate(
166+
projectLocationTransferConfigRunPathTemplate: new this._gaxModule.PathTemplate(
159167
'projects/{project}/locations/{location}/transferConfigs/{transfer_config}/runs/{run}'
160168
),
161-
projectTransferConfigPathTemplate: new gaxModule.PathTemplate(
169+
projectTransferConfigPathTemplate: new this._gaxModule.PathTemplate(
162170
'projects/{project}/transferConfigs/{transfer_config}'
163171
),
164-
projectTransferConfigRunPathTemplate: new gaxModule.PathTemplate(
172+
projectTransferConfigRunPathTemplate: new this._gaxModule.PathTemplate(
165173
'projects/{project}/transferConfigs/{transfer_config}/runs/{run}'
166174
),
167175
};
@@ -170,30 +178,30 @@ export class DataTransferServiceClient {
170178
// (e.g. 50 results at a time, with tokens to get subsequent
171179
// pages). Denote the keys used for pagination and results.
172180
this._descriptors.page = {
173-
listDataSources: new gaxModule.PageDescriptor(
181+
listDataSources: new this._gaxModule.PageDescriptor(
174182
'pageToken',
175183
'nextPageToken',
176184
'dataSources'
177185
),
178-
listTransferConfigs: new gaxModule.PageDescriptor(
186+
listTransferConfigs: new this._gaxModule.PageDescriptor(
179187
'pageToken',
180188
'nextPageToken',
181189
'transferConfigs'
182190
),
183-
listTransferRuns: new gaxModule.PageDescriptor(
191+
listTransferRuns: new this._gaxModule.PageDescriptor(
184192
'pageToken',
185193
'nextPageToken',
186194
'transferRuns'
187195
),
188-
listTransferLogs: new gaxModule.PageDescriptor(
196+
listTransferLogs: new this._gaxModule.PageDescriptor(
189197
'pageToken',
190198
'nextPageToken',
191199
'transferMessages'
192200
),
193201
};
194202

195203
// Put together the default options sent with requests.
196-
const defaults = gaxGrpc.constructSettings(
204+
this._defaults = this._gaxGrpc.constructSettings(
197205
'google.cloud.bigquery.datatransfer.v1.DataTransferService',
198206
gapicConfig as gax.ClientConfig,
199207
opts.clientConfig || {},
@@ -204,18 +212,36 @@ export class DataTransferServiceClient {
204212
// of calling the API is handled in `google-gax`, with this code
205213
// merely providing the destination and request information.
206214
this._innerApiCalls = {};
215+
}
216+
217+
/**
218+
* Initialize the client.
219+
* Performs asynchronous operations (such as authentication) and prepares the client.
220+
* This function will be called automatically when any class method is called for the
221+
* first time, but if you need to initialize it before calling an actual method,
222+
* feel free to call initialize() directly.
223+
*
224+
* You can await on this method if you want to make sure the client is initialized.
225+
*
226+
* @returns {Promise} A promise that resolves to an authenticated service stub.
227+
*/
228+
initialize() {
229+
// If the client stub promise is already initialized, return immediately.
230+
if (this.dataTransferServiceStub) {
231+
return this.dataTransferServiceStub;
232+
}
207233

208234
// Put together the "service stub" for
209235
// google.cloud.bigquery.datatransfer.v1.DataTransferService.
210-
this.dataTransferServiceStub = gaxGrpc.createStub(
211-
opts.fallback
212-
? (protos as protobuf.Root).lookupService(
236+
this.dataTransferServiceStub = this._gaxGrpc.createStub(
237+
this._opts.fallback
238+
? (this._protos as protobuf.Root).lookupService(
213239
'google.cloud.bigquery.datatransfer.v1.DataTransferService'
214240
)
215241
: // tslint:disable-next-line no-any
216-
(protos as any).google.cloud.bigquery.datatransfer.v1
242+
(this._protos as any).google.cloud.bigquery.datatransfer.v1
217243
.DataTransferService,
218-
opts
244+
this._opts
219245
) as Promise<{[method: string]: Function}>;
220246

221247
// Iterate over each of the methods that the service provides
@@ -250,9 +276,9 @@ export class DataTransferServiceClient {
250276
}
251277
);
252278

253-
const apiCall = gaxModule.createApiCall(
279+
const apiCall = this._gaxModule.createApiCall(
254280
innerCallPromise,
255-
defaults[methodName],
281+
this._defaults[methodName],
256282
this._descriptors.page[methodName] ||
257283
this._descriptors.stream[methodName] ||
258284
this._descriptors.longrunning[methodName]
@@ -266,6 +292,8 @@ export class DataTransferServiceClient {
266292
return apiCall(argument, callOptions, callback);
267293
};
268294
}
295+
296+
return this.dataTransferServiceStub;
269297
}
270298

271299
/**
@@ -399,6 +427,7 @@ export class DataTransferServiceClient {
399427
] = gax.routingHeader.fromParams({
400428
name: request.name || '',
401429
});
430+
this.initialize();
402431
return this._innerApiCalls.getDataSource(request, options, callback);
403432
}
404433
createTransferConfig(
@@ -513,6 +542,7 @@ export class DataTransferServiceClient {
513542
] = gax.routingHeader.fromParams({
514543
parent: request.parent || '',
515544
});
545+
this.initialize();
516546
return this._innerApiCalls.createTransferConfig(request, options, callback);
517547
}
518548
updateTransferConfig(
@@ -626,6 +656,7 @@ export class DataTransferServiceClient {
626656
] = gax.routingHeader.fromParams({
627657
'transfer_config.name': request.transferConfig!.name || '',
628658
});
659+
this.initialize();
629660
return this._innerApiCalls.updateTransferConfig(request, options, callback);
630661
}
631662
deleteTransferConfig(
@@ -709,6 +740,7 @@ export class DataTransferServiceClient {
709740
] = gax.routingHeader.fromParams({
710741
name: request.name || '',
711742
});
743+
this.initialize();
712744
return this._innerApiCalls.deleteTransferConfig(request, options, callback);
713745
}
714746
getTransferConfig(
@@ -791,6 +823,7 @@ export class DataTransferServiceClient {
791823
] = gax.routingHeader.fromParams({
792824
name: request.name || '',
793825
});
826+
this.initialize();
794827
return this._innerApiCalls.getTransferConfig(request, options, callback);
795828
}
796829
scheduleTransferRuns(
@@ -883,6 +916,7 @@ export class DataTransferServiceClient {
883916
] = gax.routingHeader.fromParams({
884917
parent: request.parent || '',
885918
});
919+
this.initialize();
886920
return this._innerApiCalls.scheduleTransferRuns(request, options, callback);
887921
}
888922
startManualTransferRuns(
@@ -973,6 +1007,7 @@ export class DataTransferServiceClient {
9731007
] = gax.routingHeader.fromParams({
9741008
parent: request.parent || '',
9751009
});
1010+
this.initialize();
9761011
return this._innerApiCalls.startManualTransferRuns(
9771012
request,
9781013
options,
@@ -1059,6 +1094,7 @@ export class DataTransferServiceClient {
10591094
] = gax.routingHeader.fromParams({
10601095
name: request.name || '',
10611096
});
1097+
this.initialize();
10621098
return this._innerApiCalls.getTransferRun(request, options, callback);
10631099
}
10641100
deleteTransferRun(
@@ -1141,6 +1177,7 @@ export class DataTransferServiceClient {
11411177
] = gax.routingHeader.fromParams({
11421178
name: request.name || '',
11431179
});
1180+
this.initialize();
11441181
return this._innerApiCalls.deleteTransferRun(request, options, callback);
11451182
}
11461183
checkValidCreds(
@@ -1228,6 +1265,7 @@ export class DataTransferServiceClient {
12281265
] = gax.routingHeader.fromParams({
12291266
name: request.name || '',
12301267
});
1268+
this.initialize();
12311269
return this._innerApiCalls.checkValidCreds(request, options, callback);
12321270
}
12331271

@@ -1323,6 +1361,7 @@ export class DataTransferServiceClient {
13231361
] = gax.routingHeader.fromParams({
13241362
parent: request.parent || '',
13251363
});
1364+
this.initialize();
13261365
return this._innerApiCalls.listDataSources(request, options, callback);
13271366
}
13281367

@@ -1372,6 +1411,7 @@ export class DataTransferServiceClient {
13721411
parent: request.parent || '',
13731412
});
13741413
const callSettings = new gax.CallSettings(options);
1414+
this.initialize();
13751415
return this._descriptors.page.listDataSources.createStream(
13761416
this._innerApiCalls.listDataSources as gax.GaxCall,
13771417
request,
@@ -1471,6 +1511,7 @@ export class DataTransferServiceClient {
14711511
] = gax.routingHeader.fromParams({
14721512
parent: request.parent || '',
14731513
});
1514+
this.initialize();
14741515
return this._innerApiCalls.listTransferConfigs(request, options, callback);
14751516
}
14761517

@@ -1522,6 +1563,7 @@ export class DataTransferServiceClient {
15221563
parent: request.parent || '',
15231564
});
15241565
const callSettings = new gax.CallSettings(options);
1566+
this.initialize();
15251567
return this._descriptors.page.listTransferConfigs.createStream(
15261568
this._innerApiCalls.listTransferConfigs as gax.GaxCall,
15271569
request,
@@ -1624,6 +1666,7 @@ export class DataTransferServiceClient {
16241666
] = gax.routingHeader.fromParams({
16251667
parent: request.parent || '',
16261668
});
1669+
this.initialize();
16271670
return this._innerApiCalls.listTransferRuns(request, options, callback);
16281671
}
16291672

@@ -1678,6 +1721,7 @@ export class DataTransferServiceClient {
16781721
parent: request.parent || '',
16791722
});
16801723
const callSettings = new gax.CallSettings(options);
1724+
this.initialize();
16811725
return this._descriptors.page.listTransferRuns.createStream(
16821726
this._innerApiCalls.listTransferRuns as gax.GaxCall,
16831727
request,
@@ -1778,6 +1822,7 @@ export class DataTransferServiceClient {
17781822
] = gax.routingHeader.fromParams({
17791823
parent: request.parent || '',
17801824
});
1825+
this.initialize();
17811826
return this._innerApiCalls.listTransferLogs(request, options, callback);
17821827
}
17831828

@@ -1830,6 +1875,7 @@ export class DataTransferServiceClient {
18301875
parent: request.parent || '',
18311876
});
18321877
const callSettings = new gax.CallSettings(options);
1878+
this.initialize();
18331879
return this._descriptors.page.listTransferLogs.createStream(
18341880
this._innerApiCalls.listTransferLogs as gax.GaxCall,
18351881
request,
@@ -2233,8 +2279,9 @@ export class DataTransferServiceClient {
22332279
* The client will no longer be usable and all future behavior is undefined.
22342280
*/
22352281
close(): Promise<void> {
2282+
this.initialize();
22362283
if (!this._terminated) {
2237-
return this.dataTransferServiceStub.then(stub => {
2284+
return this.dataTransferServiceStub!.then(stub => {
22382285
this._terminated = true;
22392286
stub.close();
22402287
});

0 commit comments

Comments
 (0)