Skip to content

Commit 421fc3b

Browse files
authored
Support logical termination for grpc connection (#6324)
* Support logical termination for grpc connection * Address Feedback
1 parent 578dc58 commit 421fc3b

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

packages/firestore/src/platform/node/grpc_connection.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ export class GrpcConnection implements Connection {
153153
path: string,
154154
request: Req,
155155
authToken: Token | null,
156-
appCheckToken: Token | null
156+
appCheckToken: Token | null,
157+
expectedResponseCount?: number
157158
): Promise<Resp[]> {
158159
const results: Resp[] = [];
159160
const responseDeferred = new Deferred<Resp[]>();
160-
161161
logDebug(
162162
LOG_TAG,
163163
`RPC '${rpcName}' invoked (streaming) with request:`,
@@ -172,13 +172,24 @@ export class GrpcConnection implements Connection {
172172
);
173173
const jsonRequest = { ...request, database: this.databasePath };
174174
const stream = stub[rpcName](jsonRequest, metadata);
175+
let callbackFired = false;
175176
stream.on('data', (response: Resp) => {
176177
logDebug(LOG_TAG, `RPC ${rpcName} received result:`, response);
177178
results.push(response);
179+
if (
180+
expectedResponseCount !== undefined &&
181+
results.length === expectedResponseCount
182+
) {
183+
callbackFired = true;
184+
responseDeferred.resolve(results);
185+
}
178186
});
179187
stream.on('end', () => {
180188
logDebug(LOG_TAG, `RPC '${rpcName}' completed.`);
181-
responseDeferred.resolve(results);
189+
if (!callbackFired) {
190+
callbackFired = true;
191+
responseDeferred.resolve(results);
192+
}
182193
});
183194
stream.on('error', (grpcError: grpc.ServiceError) => {
184195
logDebug(LOG_TAG, `RPC '${rpcName}' failed with error:`, grpcError);

packages/firestore/src/remote/connection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ export interface Connection {
6868
path: string,
6969
request: Req,
7070
authToken: Token | null,
71-
appCheckToken: Token | null
71+
appCheckToken: Token | null,
72+
expectedResponseCount?: number
7273
): Promise<Resp[]>;
7374

7475
/**

packages/firestore/src/remote/datastore.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ class DatastoreImpl extends Datastore {
120120
invokeStreamingRPC<Req, Resp>(
121121
rpcName: string,
122122
path: string,
123-
request: Req
123+
request: Req,
124+
expectedResponseCount?: number
124125
): Promise<Resp[]> {
125126
this.verifyInitialized();
126127
return Promise.all([
@@ -133,7 +134,8 @@ class DatastoreImpl extends Datastore {
133134
path,
134135
request,
135136
authToken,
136-
appCheckToken
137+
appCheckToken,
138+
expectedResponseCount
137139
);
138140
})
139141
.catch((error: FirestoreError) => {
@@ -194,7 +196,7 @@ export async function invokeBatchGetDocumentsRpc(
194196
const response = await datastoreImpl.invokeStreamingRPC<
195197
ProtoBatchGetDocumentsRequest,
196198
ProtoBatchGetDocumentsResponse
197-
>('BatchGetDocuments', path, request);
199+
>('BatchGetDocuments', path, request, keys.length);
198200

199201
const docs = new Map<string, Document>();
200202
response.forEach(proto => {

packages/firestore/src/remote/rest_connection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ export abstract class RestConnection implements Connection {
104104
path: string,
105105
request: Req,
106106
authToken: Token | null,
107-
appCheckToken: Token | null
107+
appCheckToken: Token | null,
108+
expectedResponseCount?: number
108109
): Promise<Resp[]> {
109110
// The REST API automatically aggregates all of the streamed results, so we
110111
// can just use the normal invoke() method.

0 commit comments

Comments
 (0)