Skip to content

Remove some object utility functions #1816

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

Merged
merged 4 commits into from
Jun 24, 2019
Merged
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
1 change: 1 addition & 0 deletions config/tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"downlevelIteration": true,
"typeRoots": ["../node_modules/@types"]
}
}
8 changes: 0 additions & 8 deletions packages/database/src/api/test_access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,6 @@ export const queryIdentifier = function(query: Query) {
return query.queryIdentifier();
};

/**
* @param {!Query} firebaseRef
* @return {!Object}
*/
export const listens = function(firebaseRef: Query) {
return (firebaseRef.repo.persistentConnection_ as any).listens_;
};

/**
* Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.
*
Expand Down
5 changes: 2 additions & 3 deletions packages/database/src/core/CompoundWrite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import { ImmutableTree } from './util/ImmutableTree';
import { Path } from './util/Path';
import { forEach } from '@firebase/util';
import { Node, NamedNode } from './snap/Node';
import { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';
import { assert } from '@firebase/util';
Expand Down Expand Up @@ -70,9 +69,9 @@ export class CompoundWrite {
*/
addWrites(path: Path, updates: { [name: string]: Node }): CompoundWrite {
let newWrite = this as CompoundWrite;
forEach(updates, function(childKey: string, node: Node) {
for (const [childKey, node] of Object.entries(updates)) {
newWrite = newWrite.addWrite(path.child(childKey), node);
});
}
return newWrite;
}

Expand Down
107 changes: 21 additions & 86 deletions packages/database/src/core/PersistentConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

import firebase from '@firebase/app';
import { forEach, contains, isEmpty, getCount, safeGet } from '@firebase/util';
import { contains, isEmpty, safeGet } from '@firebase/util';
import { stringify } from '@firebase/util';
import { assert } from '@firebase/util';
import { error, log, logWrapper, warn, ObjectToUniqueKey } from './util/util';
Expand Down Expand Up @@ -76,9 +76,8 @@ export class PersistentConnection extends ServerActions {
id = PersistentConnection.nextPersistentConnectionId_++;
private log_ = logWrapper('p:' + this.id + ':');

/** @private {Object} */
private interruptReasons_: { [reason: string]: boolean } = {};
private listens_: { [path: string]: { [queryId: string]: ListenSpec } } = {};
private readonly listens: Map<string, Map<string, ListenSpec>> = new Map();
private outstandingPuts_: OutstandingPut[] = [];
private outstandingPutCount_ = 0;
private onDisconnectRequestQueue_: OnDisconnectRequest[] = [];
Expand All @@ -88,26 +87,19 @@ export class PersistentConnection extends ServerActions {
private securityDebugCallback_: ((a: Object) => void) | null = null;
lastSessionId: string | null = null;

/** @private {number|null} */
private establishConnectionTimer_: number | null = null;

/** @private {boolean} */
private visible_: boolean = false;

// Before we get connected, we keep a queue of pending messages to send.
private requestCBHash_: { [k: number]: (a: any) => void } = {};
private requestNumber_ = 0;

/** @private {?{
* sendRequest(Object),
* close()
* }} */
private realtime_: {
sendRequest(a: Object): void;
close(): void;
} | null = null;

/** @private {string|null} */
private authToken_: string | null = null;
private forceTokenRefresh_ = false;
private invalidAuthTokenCount_ = 0;
Expand All @@ -116,26 +108,17 @@ export class PersistentConnection extends ServerActions {
private lastConnectionAttemptTime_: number | null = null;
private lastConnectionEstablishedTime_: number | null = null;

/**
* @private
*/
private static nextPersistentConnectionId_ = 0;

/**
* Counter for number of connections created. Mainly used for tagging in the logs
* @type {number}
* @private
*/
private static nextConnectionId_ = 0;

/**
* @implements {ServerActions}
* @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to
* @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server
* @param onConnectStatus_
* @param onServerInfoUpdate_
* @param authTokenProvider_
* @param authOverride_
* @param repoInfo_ Data about the namespace we are connecting to
* @param onDataUpdate_ A callback for new data from the server
*/
constructor(
private repoInfo_: RepoInfo,
Expand Down Expand Up @@ -166,12 +149,6 @@ export class PersistentConnection extends ServerActions {
}
}

/**
* @param {!string} action
* @param {*} body
* @param {function(*)=} onResponse
* @protected
*/
protected sendRequest(
action: string,
body: any,
Expand Down Expand Up @@ -203,14 +180,16 @@ export class PersistentConnection extends ServerActions {
const queryId = query.queryIdentifier();
const pathString = query.path.toString();
this.log_('Listen called for ' + pathString + ' ' + queryId);
this.listens_[pathString] = this.listens_[pathString] || {};
if (!this.listens.has(pathString)) {
this.listens.set(pathString, new Map());
}
assert(
query.getQueryParams().isDefault() ||
!query.getQueryParams().loadsAllData(),
'listen() called for non-default but complete query'
);
assert(
!this.listens_[pathString][queryId],
!this.listens.get(pathString)!.has(queryId),
'listen() called twice for same path/queryId.'
);
const listenSpec: ListenSpec = {
Expand All @@ -219,20 +198,13 @@ export class PersistentConnection extends ServerActions {
query: query,
tag: tag
};
this.listens_[pathString][queryId] = listenSpec;
this.listens.get(pathString)!.set(queryId, listenSpec);

if (this.connected_) {
this.sendListen_(listenSpec);
}
}

/**
* @param {!{onComplete(),
* hashFn():!string,
* query: !Query,
* tag: ?number}} listenSpec
* @private
*/
private sendListen_(listenSpec: ListenSpec) {
const query = listenSpec.query;
const pathString = query.path.toString();
Expand All @@ -258,7 +230,8 @@ export class PersistentConnection extends ServerActions {
PersistentConnection.warnOnListenWarnings_(payload, query);

const currentListenSpec =
this.listens_[pathString] && this.listens_[pathString][queryId];
this.listens.get(pathString) &&
this.listens.get(pathString)!.get(queryId);
// only trigger actions if the listen hasn't been removed and readded
if (currentListenSpec === listenSpec) {
this.log_('listen response', message);
Expand All @@ -274,11 +247,6 @@ export class PersistentConnection extends ServerActions {
});
}

/**
* @param {*} payload
* @param {!Query} query
* @private
*/
private static warnOnListenWarnings_(payload: any, query: Query) {
if (payload && typeof payload === 'object' && contains(payload, 'w')) {
const warnings = safeGet(payload, 'w');
Expand Down Expand Up @@ -319,10 +287,6 @@ export class PersistentConnection extends ServerActions {
this.reduceReconnectDelayIfAdminCredential_(token);
}

/**
* @param {!string} credential
* @private
*/
private reduceReconnectDelayIfAdminCredential_(credential: string) {
// NOTE: This isn't intended to be bulletproof (a malicious developer can always just modify the client).
// Additionally, we don't bother resetting the max delay back to the default if auth fails / expires.
Expand Down Expand Up @@ -576,10 +540,6 @@ export class PersistentConnection extends ServerActions {
}
}

/**
* @param {*} message
* @private
*/
private onDataMessage_(message: { [k: string]: any }) {
if ('r' in message) {
// this is a response
Expand Down Expand Up @@ -663,10 +623,6 @@ export class PersistentConnection extends ServerActions {
}, Math.floor(timeout)) as any;
}

/**
* @param {boolean} visible
* @private
*/
private onVisible_(visible: boolean) {
// NOTE: Tabbing away and back to a window will defeat our reconnect backoff, but I think that's fine.
if (
Expand Down Expand Up @@ -819,9 +775,6 @@ export class PersistentConnection extends ServerActions {
}
}

/**
* @param {string} reason
*/
interrupt(reason: string) {
log('Interrupting connection for reason: ' + reason);
this.interruptReasons_[reason] = true;
Expand All @@ -838,9 +791,6 @@ export class PersistentConnection extends ServerActions {
}
}

/**
* @param {string} reason
*/
resume(reason: string) {
log('Resuming connection for reason: ' + reason);
delete this.interruptReasons_[reason];
Expand Down Expand Up @@ -872,11 +822,6 @@ export class PersistentConnection extends ServerActions {
if (this.outstandingPutCount_ === 0) this.outstandingPuts_ = [];
}

/**
* @param {!string} pathString
* @param {Array.<*>=} query
* @private
*/
private onListenRevoked_(pathString: string, query?: any[]) {
// Remove the listen and manufacture a "permission_denied" error for the failed listen.
let queryId;
Expand All @@ -889,20 +834,15 @@ export class PersistentConnection extends ServerActions {
if (listen && listen.onComplete) listen.onComplete('permission_denied');
}

/**
* @param {!string} pathString
* @param {!string} queryId
* @return {{queries:Array.<Query>, onComplete:function(string)}}
* @private
*/
private removeListen_(pathString: string, queryId: string): ListenSpec {
const normalizedPathString = new Path(pathString).toString(); // normalize path.
let listen;
if (this.listens_[normalizedPathString] !== undefined) {
listen = this.listens_[normalizedPathString][queryId];
delete this.listens_[normalizedPathString][queryId];
if (getCount(this.listens_[normalizedPathString]) === 0) {
delete this.listens_[normalizedPathString];
if (this.listens.has(normalizedPathString)) {
const map = this.listens.get(normalizedPathString)!;
listen = map.get(queryId);
map.delete(queryId);
if (map.size === 0) {
this.listens.delete(normalizedPathString);
}
} else {
// all listens for this path has already been removed
Expand Down Expand Up @@ -948,11 +888,11 @@ export class PersistentConnection extends ServerActions {

// Puts depend on having received the corresponding data update from the server before they complete, so we must
// make sure to send listens before puts.
forEach(this.listens_, (_pathString, queries) => {
forEach(queries, (_key, listenSpec) => {
for (const queries of this.listens.values()) {
for (const listenSpec of queries.values()) {
this.sendListen_(listenSpec);
});
});
}
}

for (let i = 0; i < this.outstandingPuts_.length; i++) {
if (this.outstandingPuts_[i]) this.sendPut_(i);
Expand All @@ -971,7 +911,6 @@ export class PersistentConnection extends ServerActions {

/**
* Sends client stats for first connection
* @private
*/
private sendConnectStats_() {
const stats: { [k: string]: number } = {};
Expand All @@ -995,10 +934,6 @@ export class PersistentConnection extends ServerActions {
this.reportStats(stats);
}

/**
* @return {boolean}
* @private
*/
private shouldReconnect_(): boolean {
const online = OnlineMonitor.getInstance().currentlyOnline();
return isEmpty(this.interruptReasons_) && online;
Expand Down
27 changes: 16 additions & 11 deletions packages/database/src/core/Repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { SyncTree } from './SyncTree';
import { SnapshotHolder } from './SnapshotHolder';
import { stringify } from '@firebase/util';
import { beingCrawled, each, exceptionGuard, warn, log } from './util/util';
import { map, forEach, isEmpty } from '@firebase/util';
import { map, isEmpty } from '@firebase/util';
import { AuthTokenProvider } from './AuthTokenProvider';
import { StatsManager } from './stats/StatsManager';
import { StatsReporter } from './stats/StatsReporter';
Expand Down Expand Up @@ -403,14 +403,14 @@ export class Repo {
let empty = true;
const serverValues = this.generateServerValues();
const changedChildren: { [k: string]: Node } = {};
forEach(childrenToMerge, (changedKey: string, changedValue: any) => {
for (const [changedKey, changedValue] of Object.entries(childrenToMerge)) {
empty = false;
const newNodeUnresolved = nodeFromJSON(changedValue);
changedChildren[changedKey] = resolveDeferredValueSnapshot(
newNodeUnresolved,
serverValues
);
});
}

if (!empty) {
const writeId = this.getNextWriteId_();
Expand Down Expand Up @@ -440,10 +440,10 @@ export class Repo {
}
);

forEach(childrenToMerge, (changedPath: string) => {
for (const changedPath of Object.keys(childrenToMerge)) {
const affectedPath = this.abortTransactions_(path.child(changedPath));
this.rerunTransactions_(affectedPath);
});
}

// We queued the events above, so just flush the queue here
this.eventQueue_.raiseEventsForChangedPath(path, []);
Expand Down Expand Up @@ -566,10 +566,12 @@ export class Repo {
childrenToMerge,
(status, errorReason) => {
if (status === 'ok') {
forEach(childrenToMerge, (childName: string, childNode: any) => {
for (const [childName, childNode] of Object.entries(
childrenToMerge
)) {
const newChildNode = nodeFromJSON(childNode);
this.onDisconnect_.remember(path.child(childName), newChildNode);
});
}
}
this.callOnCompleteCallback(onComplete, status, errorReason);
}
Expand Down Expand Up @@ -651,11 +653,14 @@ export class Repo {
0
);

forEach(stats, (stat: string, value: any) => {
for (const [stat, value] of Object.entries(stats)) {
let paddedStat = stat;
// pad stat names to be the same length (plus 2 extra spaces).
for (let i = stat.length; i < longestName + 2; i++) stat += ' ';
console.log(stat + value);
});
for (let i = stat.length; i < longestName + 2; i++) {
paddedStat += ' ';
}
console.log(paddedStat + value);
}
}

statsIncrementCounter(metric: string) {
Expand Down
Loading