Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
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/
  • Loading branch information
Alec Gibson committed Aug 20, 2018
1 parent 8ff1b6a commit dd3a171
Show file tree
Hide file tree
Showing 12 changed files with 3,657 additions and 1 deletion.
14 changes: 14 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./eslint.base.yaml",
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"modules": true
}
},
"env": {
"mocha": true,
"es6": true,
"node": true
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

# IDEs
.vscode

# Runtime data
pids
*.pid
Expand Down
27 changes: 27 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
language: node_js

node_js:
- "6"
- "8"
- "10"

services:
- docker

env:
- MONGODB_VERSION="2.6"
- MONGODB_VERSION="3.6"
- MONGODB_VERSION="4.0"

before_install:
- docker run -d -p 127.0.0.1:27017:27017 mongo:$MONGODB_VERSION

before_script:
- until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done

script:
- npm run test-cover

# Send coverage data to Coveralls
after_script:
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
128 changes: 127 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,128 @@
# sharedb-milestone-mongo
A Mongo implementation of the ShareDB Milestone Database API

[![Build Status](https://travis-ci.com/share/sharedb-milestone-mongo.svg?branch=master)](https://travis-ci.com/share/sharedb-milestone-mongo.svg?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/share/sharedb-milestone-mongo/badge.svg?branch=master)](https://coveralls.io/github/share/sharedb-milestone-mongo?branch=master)

MongoDB milestone snapshot database adapter for [`sharedb`][1]. Milestone snapshots can be used to speed up the results
of ShareDB's `connection.fetchSnapshot` method by providing points in time on top of which a smaller number of ops can
be applied to reach the requested version.

Milestone snapshots will be stored in a collection called `m_COLLECTION` where `COLLECTION` is the name of your ShareDB
collection.

## Quick start

```javascript
const MongoMilestoneDB = require('sharedb-milestone-mongo');
const ShareDB = require('sharedb');

const milestoneDb = new MongoMilestoneDB('mongodb://localhost:27017/test');
const shareDb = new ShareDB({ milestoneDb: milestoneDb });
```

## Configuration

### Mongo

The underlying Mongo database can be configured in a number of ways. This library wraps v2 of the [`mongodb`][2]
library, so any configuration that can be used there can be used in this library.

Mongo can be configured simply using a connection string and any desired [options][3]:

```javascript
const milestoneDb = new MongoMilestoneDB('mongodb://localhost:27017/test', { loggerLevel: 'debug' });
```

It can also be configured with a callback that provides an instance of a Mongo [`Db` object][4]:

```javascript
const mongodb = require('mongodb');

const milestoneDb = new MongoMilestoneDB((callback) => {
mongodb.connect('mongodb://localhost:27017/test', callback);
});
```

The Mongo connection string or function can be used as the first argument of the constructor, or as part of an options
object:

```javascript
const milestoneDb = new MongoMilestoneDB({
mongo: 'mongodb://localhost:27017/test',
loggerLevel: 'debug',
});
```

### Milestone snapshot saving

#### Intervals

By default, ShareDB will save a milestone snapshot with a given frequency. This library defaults to an interval of
1,000, saving milestones when the 1,000th, 2,000th, etc. versions are committed. That default interval can be
configured:

```javascript
const milestoneDb = new MongoMilestoneDB({
mongo: 'mongodb://localhost:27017/test',
interval: 500,
});
```

#### Complex saving logic

If you need more complex saving logic (eg different intervals depending on collection), this can be achieved using
ShareDB middleware:

```javascript
const milestoneDb = new MongoMilestoneDB('mongodb://localhost:27017/test');
const shareDb = new ShareDB({ milestoneDb: milestoneDb });

shareDb.use('commit', (request, callback) => {
switch (request.collection) {
case 'foo':
// Save every 100 versions for collection 'foo'
request.saveMilestoneSnapshot = request.snapshot.v % 100 === 0;
break;
case 'bar':
case 'baz':
// Save every 500 versions for collections 'bar' and 'baz'
request.saveMilestoneSnapshot = request.snapshot.v % 500 === 0;
break;
default:
// Don't save any milestones for collections not named here.
// IMPORTANT: We have to set this to false to actively disable milestones
// If left to null, then the default interval will still apply
request.saveMilestoneSnapshot = false;
}

callback();
});
```

Note that the default value of `request.saveMilestoneSnapshot` is `null`. If left to this value, it will use the default
interval logic. If you want to actively disable snapshots, you must make sure to set it to `false`.

### Indexing

By default, indexing is enabled on the milestone collections in order to speed up fetching. This can have an adverse
impact on performance if being enabled on an existing collection that is missing the index. The indexing can be
disabled:

```javascript
const milestoneDb = new MongoMilestoneDB({
mongo: 'mongodb://localhost:27017/test',
disableIndexCreation: true,
});
```

## Error codes

### 5100 -- Internal error - DB

* 5101 -- Mongo closed


[1]: https://github.com/share/sharedb
[2]: https://mongodb.github.io/node-mongodb-native/
[3]: http://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html#connect
[4]: http://mongodb.github.io/node-mongodb-native/2.2/api/Db.html
Loading

0 comments on commit dd3a171

Please sign in to comment.