-
Notifications
You must be signed in to change notification settings - Fork 2
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
Initial implementation #1
Conversation
ddb4ee9
to
6e20dcc
Compare
6e20dcc
to
7988cb4
Compare
I'm happy to discuss what language this should be written in. I've written it in ES6 as the most modern vanilla JS that LTS Node supports (ideally I'd have liked ES7 for Other options include:
|
7988cb4
to
bb7258b
Compare
This is an initial implementation of ShareDB's [`MilestoneDB`][1]. The bare bones of `MongoMilestoneDB` connection logic are based on the [`sharedb-mongo`][2] database adapter. This adapter is a slight departure from other ShareDB code, as it is written in ES6. This is because this code is server-side-only, so we don't need to support legacy browsers and all LTS Node versions support ES6. The move should ease maintenance and understanding of asynchronous code through the use of `Promise`s, which the [`mongodb`][3] library supports out of the box. This library notably uses v2 of `mongodb` instead of the newer v3. This is to stay consistent with `sharedb-mongo`, so in theory the same config (or style of config) can be used in both `sharedb-mongo` and in `sharedb-milestone-mongo`. We also introduce usage of [`eslint`][4] instead of [`jshint`][5], which is used in other projects. `eslint` supports a much, much wider range of style rules and helps to maintain a uniform coding style. [1]: share/sharedb#236 [2]: share/sharedb-mongo [3]: mongodb.github.io/node-mongodb-native [4]: https://eslint.org/ [5]: http://jshint.com/
bb7258b
to
3c77eb3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the ShareDB PR review meeting:
lib/mongo-milestone-db.js
Outdated
mongo = options.mongo; | ||
} | ||
|
||
options = options || {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're deleting things off of the options object several lines down, let's do a shallow clone of options
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NB: The motivation for deleting these options is because the Mongo client validates them. In fact, if you pass in the option validateOptions
, then your mongo connection will actually fail if we don't tidy these up.
I'll add a comment in the code for this, too.
lib/mongo-milestone-db.js
Outdated
delete options.mongo; | ||
delete options.interval; | ||
delete options.disableIndexCreation; | ||
this._mongo = MongoMilestoneDB._connect(mongo, options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_mongoPromise
to indicate it's a promise
lib/mongo-milestone-db.js
Outdated
|
||
if (!callback) { | ||
callback = (error) => { | ||
error ? this.emit('error', error) : this.emit('save', wasSaved, collectionName, snapshot); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Nate) Ternary is a bit surprising here, I try to not use it unless I'm using the value. Switch to if-then here
lib/mongo-milestone-db.js
Outdated
}; | ||
} | ||
|
||
if (!snapshot) return process.nextTick(callback, null, wasSaved, collectionName, snapshot); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Precondition checking - Let's call back with an error here if there's no snapshot or collection name.
collectionName
and snapshot
shouldn't be necessary here, as above, you're using them from the closure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NB: To ensure consistency across database adapters, I've added these precondition test cases to the core set of tests: share/sharedb#244
lib/mongo-milestone-db.js
Outdated
} | ||
|
||
saveMilestoneSnapshot(collectionName, snapshot, callback) { | ||
let wasSaved = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From discussion to simplify API:
- Change the base MilestoneDB to return errors
- Add a new no-op (null) MilestoneDB for Share to use by default
- Remove the
wasSaved
from this API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. See here: share/sharedb#244
lib/mongo-milestone-db.js
Outdated
return this._collection(collectionName) | ||
.then((collection) => { | ||
const query = { id: snapshot.id, v: snapshot.v }; | ||
const doc = MongoMilestoneDB._shallowClone(snapshot); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See if we can remove this shallow clone, if we can't remove it, mention why we need to (Mongo driver?)
13b5d53
to
a83e5c8
Compare
@ericyhwang I've addressed the issues we discussed in the meeting. Note that this PR now has a dependency on an update to the Driver API in ShareDB core: share/sharedb#244 |
lib/mongo-milestone-db.js
Outdated
static _shallowClone(object) { | ||
if (typeof object !== 'object') return object; | ||
|
||
const out = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be written as:
return Object.assign({}, object)
Object.assign
copies enumerable own properties from the second argument (then the third arg, fourth arg, etc. if present) onto the first object. Otherwise, if doing a manual loop, a object.hasOwnProperty()
check would be needed to avoid copying over enumerable prototype properties on object
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha! I somehow completely forgot that I was in ES6 🤦🏻♂️
lib/mongo-milestone-db.js
Outdated
// collection this won't be a problem, but this is a dangerous mechanism. | ||
// Perhaps we should only warn instead of creating the indexes, especially | ||
// when there is a lot of data in the collection. | ||
return collection.createIndex({id: 1, v: 1}, {background: true, unique: true}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering, will it get confusing to have both _id
and id
properties on these Mongo documents?
One idea is to use d
, to match what the Mongo ops collections use to indicate the Share doc id. I'm open to other ideas, or staying with id
if we end up deciding that's fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mostly like using id
directly because it avoids any need for mapping the snapshots when reading/writing, but if you feel strongly we can change it. I think it quickly becomes clear which id
is which when you poke around in the data at all (if you are so inclined). And if you're poking around, you're hopefully both:
- familiar with Mongo, and therefore unsurprised by an
_id
field containing anObjectID
- familiar with ShareDB, and therefore unsurprised by an
id
field corresponding to the ShareDB doc ID
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From Share PR meeting:
- Nate prefers to use
d
as the name - See if we can use projection to rename it to
id
when reading
a83e5c8
to
372759c
Compare
@ericyhwang I've addressed the |
65bbae4
to
6f4e428
Compare
@ericyhwang I've bumped the ShareDB version so this no longer points at a fork, and I've added the Unfortunately, I don't think the Mongo lets you use |
In order to stay consistent with ops in `sharedb-mongo`, this change maps a snapshot's `id` field to `d` when storing it in Mongo, and then maps it back on fetch. This should also avoid confusion with having both an `_id` field and an `id` field.
6f4e428
to
cc68116
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Feel free to merge and publish it yourself
Released as v0.1.0. @ericyhwang and @nateps I've added you both as owners of the package. |
This is an initial implementation of ShareDB's
MilestoneDB
. Thebare bones of
MongoMilestoneDB
connection logic are based on thesharedb-mongo
database adapter.This adapter is a slight departure from other ShareDB code, as it is
written in ES6. This is because this code is server-side-only, so we
don't need to support legacy browsers and all LTS Node versions support
ES6. The move should ease maintenance and understanding of asynchronous
code through the use of
Promise
s, which themongodb
librarysupports out of the box.
This library notably uses v2 of
mongodb
instead of the newer v3. Thisis to stay consistent with
sharedb-mongo
, so in theory the same config(or style of config) can be used in both
sharedb-mongo
and insharedb-milestone-mongo
.We also introduce usage of
eslint
instead ofjshint
, whichis used in other projects.
eslint
supports a much, much wider range ofstyle rules and helps to maintain a uniform coding style.
Dependencies
NoOpMilestoneDB
implementation sharedb#244