Skip to content

Make newConnection() synchronous #3569

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 10 commits into from
Aug 10, 2020
Merged

Conversation

schmidt-sebastian
Copy link
Contributor

newConnection() doesn't need to return a Promise, which means that Datastore can be constructed synchronously.

@changeset-bot
Copy link

changeset-bot bot commented Aug 5, 2020

💥 No Changeset

Latest commit: 234d122

Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂

If these changes should be published to npm, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 5, 2020

Binary Size Report

Affected SDKs

  • @firebase/firestore

    Type Base (90203eb) Head (6df4e6d) Diff
    browser 249 kB 249 kB -218 B (-0.1%)
    esm2017 195 kB 195 kB -75 B (-0.0%)
    main 474 kB 474 kB -304 B (-0.1%)
    module 247 kB 246 kB -196 B (-0.1%)
    react-native 195 kB 195 kB -75 B (-0.0%)
  • @firebase/firestore/exp

    Type Base (90203eb) Head (6df4e6d) Diff
    browser 189 kB 189 kB -142 B (-0.1%)
    main 467 kB 467 kB -781 B (-0.2%)
    module 189 kB 189 kB -142 B (-0.1%)
    react-native 189 kB 189 kB -142 B (-0.1%)
  • @firebase/firestore/lite

    Type Base (90203eb) Head (6df4e6d) Diff
    browser 64.7 kB 64.5 kB -170 B (-0.3%)
    main 143 kB 141 kB -1.14 kB (-0.8%)
    module 64.7 kB 64.5 kB -170 B (-0.3%)
    react-native 64.8 kB 64.6 kB -170 B (-0.3%)
  • @firebase/firestore/memory

    Type Base (90203eb) Head (6df4e6d) Diff
    browser 187 kB 187 kB -218 B (-0.1%)
    esm2017 146 kB 146 kB -75 B (-0.1%)
    main 348 kB 348 kB -304 B (-0.1%)
    module 185 kB 185 kB -196 B (-0.1%)
    react-native 146 kB 146 kB -75 B (-0.1%)
  • firebase

    Type Base (90203eb) Head (6df4e6d) Diff
    firebase-firestore.js 288 kB 288 kB -198 B (-0.1%)
    firebase-firestore.memory.js 227 kB 227 kB -198 B (-0.1%)
    firebase.js 821 kB 821 kB -200 B (-0.0%)

Test Logs

Copy link

@thebrianchen thebrianchen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with some questions

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: delete extra whitespace

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -24,9 +24,9 @@ import { Connection } from '../../remote/connection';
export { newConnectivityMonitor } from '../browser/connection';

/** Initializes the HTTP connection for the REST API. */
export function newConnection(databaseInfo: DatabaseInfo): Promise<Connection> {
export function newConnection(databaseInfo: DatabaseInfo): Connection {
// node-fetch is meant to be API compatible with `fetch`, but its type don't

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bonus nit: s/don't/doesn't

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

export function newConnection(databaseInfo: DatabaseInfo): Promise<Connection> {
return Promise.resolve(new FetchConnection(databaseInfo, fetch.bind(null)));
export function newConnection(databaseInfo: DatabaseInfo): Connection {
return new FetchConnection(databaseInfo, fetch.bind(null));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why we need to bind fetch to null here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first argument to any JavaScript function is the "this context", which is this case is not used. It still has to be explicitly set as we are using "bind". If we just pass "bind" as this then calling this function pointer later would use the first argument as the "this" context... and essentially drop it.
Note that we could also do fetch.bind(this), which would be equivalent to using an array function here.

As an example, if we have a function like this:

class Foo {
bar = 'bar';

function foo() {
  console.log(this.bar);
}

function test() {
   this.foo(); // Prints 'bar';
   (() => this.foo())() // Prints 'bar', since arrow functions retain `this` context.
   this.foo().bind({bar:'foo'})(); // Different `this`. Prints 'foo'.
}

@@ -81,6 +84,6 @@ export async function removeComponents(firestore: Firestore): Promise<void> {
if (datastorePromise) {
logDebug(LOG_TAG, 'Removing Datastore');
datastoreInstances.delete(firestore);
return (await datastorePromise).termiate();
return (await datastorePromise).terminate();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/dataPromise/datastoreInstance?

You don't need the await anymore since, it's no longer a promise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -131,7 +125,7 @@ class DatastoreImpl extends Datastore {
});
}

async termiate(): Promise<void> {
async terminate(): Promise<void> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated question to this PR, but why are we making DatastoreImpl.terminate() async if the method isn't? Why does the base Datastore need to have an abstract terminate() that returns Promise<void>, considering the only implementation of the class is DatastoreImpl?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have an answer for you, so I changed this as well. In general, returning a Promise even when it is not needed can be seen as "future proofing", but this is only really needed for Public APIs that we don't want to break if there is ever a need to make them async.

@schmidt-sebastian schmidt-sebastian merged commit d3f2507 into master Aug 10, 2020
@firebase firebase locked and limited conversation to collaborators Sep 10, 2020
@schmidt-sebastian schmidt-sebastian deleted the mrschmidt/nopromise branch November 9, 2020 22:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants