Skip to content

Commit 276ebe3

Browse files
Merge
2 parents 5a28480 + 5c485dc commit 276ebe3

File tree

8 files changed

+94
-50
lines changed

8 files changed

+94
-50
lines changed

packages/firestore/src/core/sync_engine.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
802802

803803
newSnaps.push(viewChange.snapshot);
804804
const docChanges = LocalViewChanges.fromSnapshot(
805+
queryView.targetId,
805806
viewChange.snapshot
806807
);
807808
docChangesInAllViews.push(docChanges);
@@ -813,7 +814,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
813814

814815
await Promise.all(queriesProcessed);
815816
this.syncEngineListener.onWatchChange(newSnaps);
816-
await this.localStore.notifyLocalViewChanges(docChangesInAllViews);
817+
this.localStore.notifyLocalViewChanges(docChangesInAllViews);
817818
// TODO(multitab): Multitab garbage collection
818819
if (this.isPrimary) {
819820
await this.localStore

packages/firestore/src/local/local_store.ts

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -632,36 +632,17 @@ export class LocalStore {
632632
/**
633633
* Notify local store of the changed views to locally pin documents.
634634
*/
635-
notifyLocalViewChanges(viewChanges: LocalViewChanges[]): Promise<void> {
636-
return this.persistence.runTransaction(
637-
'Notify local view changes',
638-
false,
639-
txn => {
640-
const promises = [] as Array<PersistencePromise<void>>;
641-
for (const view of viewChanges) {
642-
promises.push(
643-
this.queryCache
644-
.getQueryData(txn, view.query)
645-
.next((queryData: QueryData | null) => {
646-
assert(
647-
queryData !== null,
648-
'Local view changes contain unallocated query.'
649-
);
650-
const targetId = queryData!.targetId;
651-
this.localViewReferences.addReferences(
652-
view.addedKeys,
653-
targetId
654-
);
655-
this.localViewReferences.removeReferences(
656-
view.removedKeys,
657-
targetId
658-
);
659-
})
660-
);
661-
}
662-
return PersistencePromise.waitFor(promises);
663-
}
664-
);
635+
notifyLocalViewChanges(viewChanges: LocalViewChanges[]): void {
636+
for (const viewChange of viewChanges) {
637+
this.localViewReferences.addReferences(
638+
viewChange.addedKeys,
639+
viewChange.targetId
640+
);
641+
this.localViewReferences.removeReferences(
642+
viewChange.removedKeys,
643+
viewChange.targetId
644+
);
645+
}
665646
}
666647

667648
/**

packages/firestore/src/local/local_view_changes.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { Query } from '../core/query';
1817
import { ChangeType, ViewSnapshot } from '../core/view_snapshot';
1918
import { documentKeySet, DocumentKeySet } from '../model/collections';
19+
import { TargetId } from '../core/types';
2020

2121
/**
2222
* A set of changes to what documents are currently in view and out of view for
@@ -25,12 +25,15 @@ import { documentKeySet, DocumentKeySet } from '../model/collections';
2525
*/
2626
export class LocalViewChanges {
2727
constructor(
28-
readonly query: Query,
28+
readonly targetId: TargetId,
2929
readonly addedKeys: DocumentKeySet,
3030
readonly removedKeys: DocumentKeySet
3131
) {}
3232

33-
static fromSnapshot(viewSnapshot: ViewSnapshot): LocalViewChanges {
33+
static fromSnapshot(
34+
targetId: TargetId,
35+
viewSnapshot: ViewSnapshot
36+
): LocalViewChanges {
3437
let addedKeys = documentKeySet();
3538
let removedKeys = documentKeySet();
3639

@@ -47,6 +50,6 @@ export class LocalViewChanges {
4750
}
4851
}
4952

50-
return new LocalViewChanges(viewSnapshot.query, addedKeys, removedKeys);
53+
return new LocalViewChanges(targetId, addedKeys, removedKeys);
5154
}
5255
}

packages/firestore/test/integration/api/fields.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import {
2424
withTestCollectionSettings,
2525
withTestDoc
2626
} from '../util/helpers';
27+
import * as log from '../../../src/util/log';
28+
import { LogLevel } from '../../../src/util/log';
2729

2830
const FieldPath = firebase.firestore.FieldPath;
2931
const Timestamp = firebase.firestore.Timestamp;
@@ -349,12 +351,18 @@ apiDescribe('Timestamp Fields in snapshots', persistence => {
349351
};
350352

351353
it('are returned as native dates if timestampsInSnapshots is not set', () => {
354+
// Avoid the verbose log message triggered by timestampsInSnapshots ==
355+
// false.
356+
const logLevel = log.getLogLevel();
357+
log.setLogLevel(LogLevel.SILENT);
358+
352359
const settings = { ...DEFAULT_SETTINGS };
353360
settings['timestampsInSnapshots'] = false;
354361

355362
const timestamp = new Timestamp(100, 123456789);
356363
const testDocs = { a: testDataWithTimestamps(timestamp) };
357364
return withTestCollectionSettings(persistence, settings, testDocs, coll => {
365+
log.setLogLevel(logLevel);
358366
return coll
359367
.doc('a')
360368
.get()
@@ -411,13 +419,17 @@ apiDescribe('Timestamp Fields in snapshots', persistence => {
411419
});
412420

413421
it('timestampsInSnapshots affects server timestamps', () => {
422+
const logLevel = log.getLogLevel();
423+
log.setLogLevel(LogLevel.SILENT);
424+
414425
const settings = { ...DEFAULT_SETTINGS };
415426
settings['timestampsInSnapshots'] = false;
416427
const testDocs = {
417428
a: { timestamp: firebase.firestore.FieldValue.serverTimestamp() }
418429
};
419430

420431
return withTestCollectionSettings(persistence, settings, testDocs, coll => {
432+
log.setLogLevel(logLevel);
421433
return coll
422434
.doc('a')
423435
.get()

packages/firestore/test/unit/local/local_store.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ class LocalStoreTester {
116116
}
117117

118118
afterViewChanges(viewChanges: LocalViewChanges): LocalStoreTester {
119-
this.promiseChain = this.promiseChain.then(() => {
120-
return this.localStore.notifyLocalViewChanges([viewChanges]);
121-
});
119+
this.promiseChain = this.promiseChain.then(() =>
120+
this.localStore.notifyLocalViewChanges([viewChanges])
121+
);
122122
return this;
123123
}
124124

@@ -790,14 +790,14 @@ function genericLocalStoreTests(
790790
.afterGC()
791791
.toContain(doc('foo/bar', 1, { foo: 'bar' }))
792792
.toContain(doc('foo/baz', 0, { foo: 'baz' }, { hasLocalMutations: true }))
793-
.after(localViewChanges(query, { added: ['foo/bar', 'foo/baz'] }))
793+
.after(localViewChanges(2, { added: ['foo/bar', 'foo/baz'] }))
794794
.after(docUpdateRemoteEvent(doc('foo/bar', 1, { foo: 'bar' }), [], [2]))
795795
.after(docUpdateRemoteEvent(doc('foo/baz', 2, { foo: 'baz' }), [2]))
796796
.afterAcknowledgingMutation({ documentVersion: 2 })
797797
.afterGC()
798798
.toContain(doc('foo/bar', 1, { foo: 'bar' }))
799799
.toContain(doc('foo/baz', 2, { foo: 'baz' }))
800-
.after(localViewChanges(query, { removed: ['foo/bar', 'foo/baz'] }))
800+
.after(localViewChanges(2, { removed: ['foo/bar', 'foo/baz'] }))
801801
.afterReleasingQuery(query)
802802
.afterGC()
803803
.toNotContain('foo/bar')

packages/firestore/test/unit/specs/perf_spec.test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import { Query } from '../../../src/core/query';
18-
import { doc, orderBy, path } from '../../util/helpers';
18+
import { doc, filter, orderBy, path } from '../../util/helpers';
1919

2020
import { describeSpec, specTest } from './describe_spec';
2121
import { spec } from './spec_builder';
@@ -242,5 +242,52 @@ describeSpec(
242242
return steps;
243243
}
244244
);
245+
246+
specTest('Process 25 target updates and wait for snapshot', [], () => {
247+
const queriesPerStep = 25;
248+
249+
let currentVersion = 1;
250+
let steps = spec().withGCEnabled(false);
251+
252+
for (let i = 1; i <= STEP_COUNT; ++i) {
253+
// We use a different subcollection for each iteration to ensure
254+
// that we use distinct and non-overlapping collection queries.
255+
const collPath = `collection/${i}/coll`;
256+
const matchingDoc = doc(`${collPath}/matches`, ++currentVersion, {
257+
val: -1
258+
});
259+
260+
const queries = [];
261+
262+
// Create `queriesPerStep` listens, each against collPath but with a
263+
// unique query constraint.
264+
for (let j = 0; j < queriesPerStep; ++j) {
265+
const query = Query.atPath(path(collPath)).addFilter(
266+
filter('val', '<=', j)
267+
);
268+
queries.push(query);
269+
steps = steps.userListens(query).watchAcks(query);
270+
}
271+
272+
steps = steps
273+
.watchSends({ affects: queries }, matchingDoc)
274+
.watchSnapshots(++currentVersion);
275+
276+
// Registers the snapshot expectations with the spec runner.
277+
for (const query of queries) {
278+
steps = steps.expectEvents(query, {
279+
added: [matchingDoc],
280+
fromCache: true
281+
});
282+
}
283+
284+
// Unlisten and clean up the query.
285+
for (const query of queries) {
286+
steps = steps.userUnlistens(query).watchRemoves(query);
287+
}
288+
}
289+
290+
return steps;
291+
});
245292
}
246293
);

packages/firestore/test/util/api_helpers.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,16 @@ export const FIRESTORE = new Firestore({
4646
});
4747

4848
export function firestore(): Firestore {
49+
FIRESTORE.settings({ timestampsInSnapshots: true });
4950
return FIRESTORE;
5051
}
5152

5253
export function collectionReference(path: string): CollectionReference {
53-
return new CollectionReference(pathFrom(path), FIRESTORE);
54+
return new CollectionReference(pathFrom(path), firestore());
5455
}
5556

5657
export function documentReference(path: string): DocumentReference {
57-
return new DocumentReference(key(path), FIRESTORE);
58+
return new DocumentReference(key(path), firestore());
5859
}
5960

6061
export function documentSnapshot(
@@ -64,18 +65,18 @@ export function documentSnapshot(
6465
): DocumentSnapshot {
6566
if (data) {
6667
return new DocumentSnapshot(
67-
FIRESTORE,
68+
firestore(),
6869
key(path),
6970
doc(path, 1, data),
7071
fromCache
7172
);
7273
} else {
73-
return new DocumentSnapshot(FIRESTORE, key(path), null, fromCache);
74+
return new DocumentSnapshot(firestore(), key(path), null, fromCache);
7475
}
7576
}
7677

7778
export function query(path: string): Query {
78-
return new Query(InternalQuery.atPath(pathFrom(path)), FIRESTORE);
79+
return new Query(InternalQuery.atPath(pathFrom(path)), firestore());
7980
}
8081

8182
/**
@@ -121,5 +122,5 @@ export function querySnapshot(
121122
syncStateChanged,
122123
/* excludesMetadataChanges= */ false
123124
);
124-
return new QuerySnapshot(FIRESTORE, query, viewSnapshot);
125+
return new QuerySnapshot(firestore(), query, viewSnapshot);
125126
}

packages/firestore/test/util/helpers.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
Direction,
3131
Filter,
3232
OrderBy,
33-
Query,
3433
RelationOp
3534
} from '../../src/core/query';
3635
import { SnapshotVersion } from '../../src/core/snapshot_version';
@@ -375,7 +374,7 @@ export function limboChanges(changes: {
375374
}
376375

377376
export function localViewChanges(
378-
query: Query,
377+
targetId: TargetId,
379378
changes: { added?: string[]; removed?: string[] }
380379
): LocalViewChanges {
381380
if (!changes.added) changes.added = [];
@@ -390,7 +389,7 @@ export function localViewChanges(
390389
keyStr => (removedKeys = removedKeys.add(key(keyStr)))
391390
);
392391

393-
return new LocalViewChanges(query, addedKeys, removedKeys);
392+
return new LocalViewChanges(targetId, addedKeys, removedKeys);
394393
}
395394

396395
/** Creates a resume token to match the given snapshot version. */

0 commit comments

Comments
 (0)