Skip to content

Commit a5e16d4

Browse files
Adding readwrite-primary mode (#1203)
1 parent dbc8d70 commit a5e16d4

10 files changed

+508
-418
lines changed

packages/firestore/src/local/indexeddb_persistence.ts

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -436,51 +436,55 @@ export class IndexedDbPersistence implements Persistence {
436436
let activeClients: DbClientMetadata[];
437437
let inactiveClients: DbClientMetadata[] = [];
438438

439-
await this.runTransaction('readwrite', true, txn => {
440-
const metadataStore = IndexedDbPersistence.getStore<
441-
DbClientMetadataKey,
442-
DbClientMetadata
443-
>(txn, DbClientMetadata.store);
444-
445-
return metadataStore
446-
.loadAll()
447-
.next(existingClients => {
448-
activeClients = this.filterActiveClients(
449-
existingClients,
450-
CLIENT_STATE_GARBAGE_COLLECTION_THRESHOLD_MS
451-
);
452-
inactiveClients = existingClients.filter(
453-
client => activeClients.indexOf(client) === -1
454-
);
455-
})
456-
.next(() =>
457-
// Delete metadata for clients that are no longer considered active.
458-
PersistencePromise.forEach(inactiveClients, inactiveClient =>
459-
metadataStore.delete(inactiveClient.clientId)
460-
)
461-
)
462-
.next(() => {
463-
// Retrieve the minimum change ID from the set of active clients.
464-
465-
// The primary client doesn't read from the document change log,
466-
// and hence we exclude it when we determine the minimum
467-
// `lastProcessedDocumentChangeId`.
468-
activeClients = activeClients.filter(
469-
client => client.clientId !== this.clientId
470-
);
471-
472-
if (activeClients.length > 0) {
473-
const processedChangeIds = activeClients.map(
474-
client => client.lastProcessedDocumentChangeId || 0
439+
await this.runTransaction(
440+
'maybeGarbageCollectMultiClientState',
441+
'readwrite-primary',
442+
txn => {
443+
const metadataStore = IndexedDbPersistence.getStore<
444+
DbClientMetadataKey,
445+
DbClientMetadata
446+
>(txn, DbClientMetadata.store);
447+
448+
return metadataStore
449+
.loadAll()
450+
.next(existingClients => {
451+
activeClients = this.filterActiveClients(
452+
existingClients,
453+
CLIENT_STATE_GARBAGE_COLLECTION_THRESHOLD_MS
475454
);
476-
const oldestChangeId = Math.min(...processedChangeIds);
477-
return this.remoteDocumentCache.removeDocumentChangesThroughChangeId(
478-
txn,
479-
oldestChangeId
455+
inactiveClients = existingClients.filter(
456+
client => activeClients.indexOf(client) === -1
480457
);
481-
}
482-
});
483-
});
458+
})
459+
.next(() =>
460+
// Delete metadata for clients that are no longer considered active.
461+
PersistencePromise.forEach(inactiveClients, inactiveClient =>
462+
metadataStore.delete(inactiveClient.clientId)
463+
)
464+
)
465+
.next(() => {
466+
// Retrieve the minimum change ID from the set of active clients.
467+
468+
// The primary client doesn't read from the document change log,
469+
// and hence we exclude it when we determine the minimum
470+
// `lastProcessedDocumentChangeId`.
471+
activeClients = activeClients.filter(
472+
client => client.clientId !== this.clientId
473+
);
474+
475+
if (activeClients.length > 0) {
476+
const processedChangeIds = activeClients.map(
477+
client => client.lastProcessedDocumentChangeId || 0
478+
);
479+
const oldestChangeId = Math.min(...processedChangeIds);
480+
return this.remoteDocumentCache.removeDocumentChangesThroughChangeId(
481+
txn,
482+
oldestChangeId
483+
);
484+
}
485+
});
486+
}
487+
);
484488

485489
// Delete potential leftover entries that may continue to mark the
486490
// inactive clients as zombied in LocalStorage.
@@ -712,7 +716,7 @@ export class IndexedDbPersistence implements Persistence {
712716

713717
runTransaction<T>(
714718
action: string,
715-
requirePrimaryLease: boolean,
719+
mode: 'readonly' | 'readwrite' | 'readwrite-primary',
716720
transactionOperation: (
717721
transaction: PersistenceTransaction
718722
) => PersistencePromise<T>
@@ -724,10 +728,10 @@ export class IndexedDbPersistence implements Persistence {
724728
// Do all transactions as readwrite against all object stores, since we
725729
// are the only reader/writer.
726730
return this.simpleDb.runTransaction(
727-
'readwrite',
731+
mode === 'readonly' ? 'readonly' : 'readwrite',
728732
ALL_STORES,
729733
simpleDbTxn => {
730-
if (requirePrimaryLease) {
734+
if (mode === 'readwrite-primary') {
731735
// While we merely verify that we have (or can acquire) the lease
732736
// immediately, we wait to extend the primary lease until after
733737
// executing transactionOperation(). This ensures that even if the

0 commit comments

Comments
 (0)