Skip to content

firestore: add extra logging into simple_db.ts #9163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/firestore/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ export { debugAssert as _debugAssert } from './util/assert';
export { FieldPath as _FieldPath } from './model/path';
export type { ResourcePath as _ResourcePath } from './model/path';
export { ByteString as _ByteString } from './util/byte_string';
export { logWarn as _logWarn } from './util/log';
export {
logWarn as _logWarn,
enableLogBuffer as _enableLogBuffer,
dumpLogBuffer as _dumpLogBuffer
} from './util/log';
export { AutoId as _AutoId } from './util/misc';
export type {
AuthTokenFactory,
Expand Down
34 changes: 32 additions & 2 deletions packages/firestore/src/api/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ import { LRU_MINIMUM_CACHE_SIZE_BYTES } from '../local/lru_garbage_collector_imp
import { debugAssert } from '../util/assert';
import { AsyncQueue } from '../util/async_queue';
import { AsyncQueueImpl } from '../util/async_queue_impl';
import { generateUniqueDebugId } from '../util/debug_uid';
import { Code, FirestoreError } from '../util/error';
import { cast } from '../util/input_validation';
import { logWarn } from '../util/log';
import { logDebug, logWarn } from '../util/log';
import { Deferred } from '../util/promise';

import { LoadBundleTask } from './bundle';
Expand Down Expand Up @@ -94,6 +95,7 @@ export const CACHE_SIZE_UNLIMITED = LRU_COLLECTION_DISABLED;
* Do not call this constructor directly. Instead, use {@link (getFirestore:1)}.
*/
export class Firestore extends LiteFirestore {
readonly _debugId = `Firestore@${generateUniqueDebugId()}`;
/**
* Whether it's a {@link Firestore} or Firestore Lite instance.
*/
Expand Down Expand Up @@ -204,10 +206,20 @@ export function initializeFirestore(
void pingServer(settings.host);
}

return provider.initialize({
const db = provider.initialize({
options: settings,
instanceIdentifier: databaseId
});

logDebug(
`initializeFirestore(` +
`app.name=${app.name ?? 'undefined'}, databaseId=${
databaseId ?? 'undefined'
}` +
`) returns ${db._debugId}`
);

return db;
}

/**
Expand Down Expand Up @@ -269,6 +281,15 @@ export function getFirestore(
connectFirestoreEmulator(db, ...emulator);
}
}

logDebug(
`getFirestore(` +
`app.name=${app.name ?? 'undefined'}, databaseId=${
databaseId ?? 'undefined'
}` +
`) returns ${db._debugId}`
);

return db;
}

Expand Down Expand Up @@ -323,6 +344,7 @@ export function configureFirestore(firestore: Firestore): void {
firestore._componentsProvider &&
buildComponentProvider(firestore._componentsProvider)
);
logDebug(`${firestore._firestoreClient} created by ${firestore._debugId}`);
}

function buildComponentProvider(componentsProvider: {
Expand Down Expand Up @@ -500,6 +522,8 @@ export function clearIndexedDbPersistence(firestore: Firestore): Promise<void> {
);
}

logDebug(firestore._debugId, 'clearIndexedDbPersistence()');

const deferred = new Deferred<void>();
firestore._queue.enqueueAndForgetEvenWhileRestricted(async () => {
try {
Expand Down Expand Up @@ -531,6 +555,7 @@ export function clearIndexedDbPersistence(firestore: Firestore): Promise<void> {
* acknowledged by the backend.
*/
export function waitForPendingWrites(firestore: Firestore): Promise<void> {
logDebug(firestore._debugId, 'waitForPendingWrites()');
firestore = cast(firestore, Firestore);
const client = ensureFirestoreConfigured(firestore);
return firestoreClientWaitForPendingWrites(client);
Expand All @@ -543,6 +568,7 @@ export function waitForPendingWrites(firestore: Firestore): Promise<void> {
* @returns A `Promise` that is resolved once the network has been enabled.
*/
export function enableNetwork(firestore: Firestore): Promise<void> {
logDebug(firestore._debugId, 'enableNetwork()');
firestore = cast(firestore, Firestore);
const client = ensureFirestoreConfigured(firestore);
return firestoreClientEnableNetwork(client);
Expand All @@ -557,6 +583,7 @@ export function enableNetwork(firestore: Firestore): Promise<void> {
* @returns A `Promise` that is resolved once the network has been disabled.
*/
export function disableNetwork(firestore: Firestore): Promise<void> {
logDebug(firestore._debugId, 'disableNetwork()');
firestore = cast(firestore, Firestore);
const client = ensureFirestoreConfigured(firestore);
return firestoreClientDisableNetwork(client);
Expand Down Expand Up @@ -585,6 +612,7 @@ export function disableNetwork(firestore: Firestore): Promise<void> {
* terminated.
*/
export function terminate(firestore: Firestore): Promise<void> {
logDebug(firestore._debugId, 'terminate()');
_removeServiceInstance(
firestore.app,
'firestore',
Expand All @@ -608,6 +636,7 @@ export function loadBundle(
firestore: Firestore,
bundleData: ReadableStream<Uint8Array> | ArrayBuffer | string
): LoadBundleTask {
logDebug(firestore._debugId, 'loadBundle()');
firestore = cast(firestore, Firestore);
const client = ensureFirestoreConfigured(firestore);
const resultTask = new LoadBundleTask();
Expand Down Expand Up @@ -636,6 +665,7 @@ export function namedQuery(
firestore: Firestore,
name: string
): Promise<Query | null> {
logDebug(firestore._debugId, 'namedQuery() name:', name);
firestore = cast(firestore, Firestore);
const client = ensureFirestoreConfigured(firestore);
return firestoreClientGetNamedQuery(client, name).then(namedQuery => {
Expand Down
26 changes: 24 additions & 2 deletions packages/firestore/src/core/component_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ import {
import { JsonProtoSerializer } from '../remote/serializer';
import { hardAssert } from '../util/assert';
import { AsyncQueue } from '../util/async_queue';
import { generateUniqueDebugId } from '../util/debug_uid';
import { Code, FirestoreError } from '../util/error';
import { logDebug } from '../util/log';

import { DatabaseInfo } from './database_info';
import { EventManager, newEventManager } from './event_manager';
Expand All @@ -78,6 +80,8 @@ import { OnlineStateSource } from './types';
type Kind = 'memory' | 'persistent';

export interface ComponentConfiguration {
readonly debugId: string;

asyncQueue: AsyncQueue;
databaseInfo: DatabaseInfo;
authCredentials: CredentialsProvider<User>;
Expand All @@ -96,6 +100,7 @@ export interface OfflineComponentProviderFactory {
* cache. Implementations override `initialize()` to provide all components.
*/
export interface OfflineComponentProvider {
readonly debugId: string;
readonly kind: Kind;
persistence: Persistence;
sharedClientState: SharedClientState;
Expand All @@ -116,8 +121,13 @@ export interface OfflineComponentProvider {
export class MemoryOfflineComponentProvider
implements OfflineComponentProvider
{
readonly debugId: string;
kind: Kind = 'memory';

constructor() {
this.debugId = `MemoryOfflineComponentProvider@${generateUniqueDebugId()}`;
}

static readonly provider: OfflineComponentProviderFactory = {
build: () => new MemoryOfflineComponentProvider()
};
Expand Down Expand Up @@ -171,7 +181,12 @@ export class MemoryOfflineComponentProvider
}

createPersistence(cfg: ComponentConfiguration): Persistence {
return new MemoryPersistence(MemoryEagerDelegate.factory, this.serializer);
const persistence = new MemoryPersistence(
MemoryEagerDelegate.factory,
this.serializer
);
logDebug(`${persistence.debugId} created from ${this.debugId}`);
return persistence;
}

createSharedClientState(cfg: ComponentConfiguration): SharedClientState {
Expand Down Expand Up @@ -222,6 +237,7 @@ export class LruGcMemoryOfflineComponentProvider extends MemoryOfflineComponentP
* Provides all components needed for Firestore with IndexedDB persistence.
*/
export class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentProvider {
readonly debugId: string;
kind: Kind = 'persistent';
persistence!: IndexedDbPersistence;
sharedClientState!: SharedClientState;
Expand All @@ -236,6 +252,7 @@ export class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentPro
protected readonly forceOwnership: boolean | undefined
) {
super();
this.debugId = `IndexedDbOfflineComponentProvider@${generateUniqueDebugId()}`;
}

async initialize(cfg: ComponentConfiguration): Promise<void> {
Expand Down Expand Up @@ -301,7 +318,7 @@ export class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentPro
? LruParams.withCacheSize(this.cacheSizeBytes)
: LruParams.DEFAULT;

return new IndexedDbPersistence(
const persistence = new IndexedDbPersistence(
this.synchronizeTabs,
persistenceKey,
cfg.clientId,
Expand All @@ -313,6 +330,10 @@ export class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentPro
this.sharedClientState,
!!this.forceOwnership
);

logDebug(`${persistence.debugId} created from ${this.debugId}`);

return persistence;
}

createSharedClientState(cfg: ComponentConfiguration): SharedClientState {
Expand Down Expand Up @@ -467,6 +488,7 @@ export class OnlineComponentProvider {
createDatastore(cfg: ComponentConfiguration): Datastore {
const serializer = newSerializer(cfg.databaseInfo.databaseId);
const connection = newConnection(cfg.databaseInfo);
logDebug(`${connection.debugId} created for ${cfg.debugId}`);
return newDatastore(
cfg.authCredentials,
cfg.appCheckCredentials,
Expand Down
26 changes: 17 additions & 9 deletions packages/firestore/src/core/firestore_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { AsyncQueue, wrapInUserErrorIfRecoverable } from '../util/async_queue';
import { BundleReader, BundleReaderSync } from '../util/bundle_reader';
import { newBundleReader } from '../util/bundle_reader_impl';
import { newBundleReaderSync } from '../util/bundle_reader_sync_impl';
import { generateUniqueDebugId } from '../util/debug_uid';
import { Code, FirestoreError } from '../util/error';
import { logDebug, logWarn } from '../util/log';
import { AutoId } from '../util/misc';
Expand Down Expand Up @@ -98,7 +99,6 @@ import { TransactionRunner } from './transaction_runner';
import { View } from './view';
import { ViewSnapshot } from './view_snapshot';

const LOG_TAG = 'FirestoreClient';
export const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100;

/** DOMException error code constants. */
Expand All @@ -112,6 +112,8 @@ const DOM_EXCEPTION_QUOTA_EXCEEDED = 22;
* async queue that is shared by all of the other components in the system. //
*/
export class FirestoreClient {
readonly debugId = `FirestoreClient@${generateUniqueDebugId()}`;

private user = User.UNAUTHENTICATED;
private readonly clientId = AutoId.newId();
private authCredentialListener: CredentialChangeListener<User> = () =>
Expand Down Expand Up @@ -148,18 +150,19 @@ export class FirestoreClient {
) {
this._uninitializedComponentsProvider = componentProvider;
this.authCredentials.start(asyncQueue, async user => {
logDebug(LOG_TAG, 'Received user=', user.uid);
logDebug(this.debugId, 'Received user=', user.uid);
await this.authCredentialListener(user);
this.user = user;
});
this.appCheckCredentials.start(asyncQueue, newAppCheckToken => {
logDebug(LOG_TAG, 'Received new app check token=', newAppCheckToken);
logDebug(this.debugId, 'Received new app check token=', newAppCheckToken);
return this.appCheckCredentialListener(newAppCheckToken, this.user);
});
}

get configuration(): ComponentConfiguration {
return {
debugId: this.debugId,
asyncQueue: this.asyncQueue,
databaseInfo: this.databaseInfo,
clientId: this.clientId,
Expand Down Expand Up @@ -216,7 +219,7 @@ export async function setOfflineComponentProvider(
): Promise<void> {
client.asyncQueue.verifyOperationInProgress();

logDebug(LOG_TAG, 'Initializing OfflineComponentProvider');
logDebug(client.debugId, 'Initializing OfflineComponentProvider');
const configuration = client.configuration;
await offlineComponentProvider.initialize(configuration);

Expand Down Expand Up @@ -260,7 +263,7 @@ export async function setOnlineComponentProvider(

const offlineComponents = await ensureOfflineComponents(client);

logDebug(LOG_TAG, 'Initializing OnlineComponentProvider');
logDebug(client.debugId, 'Initializing OnlineComponentProvider');
await onlineComponentProvider.initialize(
offlineComponents,
client.configuration
Expand Down Expand Up @@ -319,7 +322,7 @@ async function ensureOfflineComponents(
): Promise<OfflineComponentProvider> {
if (!client._offlineComponents) {
if (client._uninitializedComponentsProvider) {
logDebug(LOG_TAG, 'Using user provided OfflineComponentProvider');
logDebug(client.debugId, 'Using user provided OfflineComponentProvider');
try {
await setOfflineComponentProvider(
client,
Expand All @@ -341,12 +344,17 @@ async function ensureOfflineComponents(
);
}
} else {
logDebug(LOG_TAG, 'Using default OfflineComponentProvider');
logDebug(client.debugId, 'Using default OfflineComponentProvider');
await setOfflineComponentProvider(
client,
new LruGcMemoryOfflineComponentProvider(undefined)
);
}
logDebug(
`${client.debugId} using OfflineComponentProvider: ${
client._offlineComponents!.debugId
}`
);
}

return client._offlineComponents!;
Expand All @@ -357,13 +365,13 @@ export async function ensureOnlineComponents(
): Promise<OnlineComponentProvider> {
if (!client._onlineComponents) {
if (client._uninitializedComponentsProvider) {
logDebug(LOG_TAG, 'Using user provided OnlineComponentProvider');
logDebug(client.debugId, 'Using user provided OnlineComponentProvider');
await setOnlineComponentProvider(
client,
client._uninitializedComponentsProvider._online
);
} else {
logDebug(LOG_TAG, 'Using default OnlineComponentProvider');
logDebug(client.debugId, 'Using default OnlineComponentProvider');
await setOnlineComponentProvider(client, new OnlineComponentProvider());
}
}
Expand Down
Loading
Loading