autoensure indexes when starting app

This commit is contained in:
Andris Reinman 2017-03-20 23:19:25 +02:00
parent 4bbeedf050
commit efae1fb91e
6 changed files with 145 additions and 146 deletions

View file

@ -94,23 +94,7 @@ $ npm install --production
You can either modify the default [config file](./config/default.js) or alternatively generate an environment related config file that gets merged with the default values. Read about the config module [here](https://www.npmjs.com/package/config)
### Step 4. Add indexes
Run the [index queries](./indexes.js) in MongoDB (optional, the app would work without it as indexes only become relevant once you have more than few messages stored)
There's a helper script that you can run from the command line to add/updated indexes in the database provided by the configuration file
```
$ npm run indexes
```
Or if you want to use mongo settings from environment related config file, eg from `production.js`, run the following
```
$ NODE_ENV=production npm run indexes
```
### Step 5. Run the server
### Step 4. Run the server
To use the default config file, run the following

View file

@ -1,4 +0,0 @@
'use strict';
// reveal mongodb settings based on current environment
const config = require('config');
process.stdout.write(config.mongo);

61
imap.js
View file

@ -14,6 +14,7 @@ const ObjectID = require('mongodb').ObjectID;
const Indexer = require('./imap-core/lib/indexer/indexer');
const fs = require('fs');
const RedFour = require('redfour');
const setupIndexes = require('./indexes.json');
// Setup server
const serverOptions = {
@ -1279,38 +1280,54 @@ server.addToMailbox = (username, path, meta, date, flags, raw, callback) => {
module.exports = done => {
MongoClient.connect(config.mongo, (err, db) => {
if (err) {
server.logger.error('Queue', 'Could not initialize MongoDB: %s', err.message);
server.logger.error('Could not initialize MongoDB: %s', err.message);
return;
}
database = db;
server.indexer = new Indexer({
database
});
// setup notification system for updates
server.notifier = new ImapNotifier({
database
});
let start = () => {
let started = false;
server.on('error', err => {
if (!started) {
server.indexer = new Indexer({
database
});
// setup notification system for updates
server.notifier = new ImapNotifier({
database
});
let started = false;
server.on('error', err => {
if (!started) {
started = true;
return done(err);
}
log.error('IMAP', err);
});
// start listening
server.listen(config.imap.port, config.imap.host, () => {
if (started) {
return server.close();
}
started = true;
return done(err);
}
log.error('IMAP', err);
});
done(null, server);
});
};
// start listening
server.listen(config.imap.port, config.imap.host, () => {
if (started) {
return server.close();
let indexpos = 0;
let ensureIndexes = () => {
if (indexpos >= setupIndexes.length) {
log.info('mongo', 'Setup indexes for %s collections', setupIndexes.length);
return start();
}
started = true;
done(null, server);
});
let index = setupIndexes[indexpos++];
database.collection(index.collection).createIndexes(index.indexes, ensureIndexes);
};
ensureIndexes();
});
};

View file

@ -1,100 +0,0 @@
/* global db */
'use strict';
db.users.createIndex({
username: 1
});
db.mailboxes.createIndex({
username: 1
});
db.mailboxes.createIndex({
username: 1,
path: 1
});
db.mailboxes.createIndex({
username: 1,
subscribed: 1
});
db.messages.createIndex({
mailbox: 1
});
db.messages.createIndex({
mailbox: 1,
unseen: 1
});
db.messages.createIndex({
mailbox: 1,
uid: 1
});
db.messages.createIndex({
mailbox: 1,
uid: 1,
modseq: 1
});
db.messages.createIndex({
mailbox: 1,
flags: 1
});
db.messages.createIndex({
modseq: 1
});
db.messages.createIndex({
modseq: -1
});
db.messages.createIndex({
flags: 1
});
db.messages.createIndex({
internaldate: 1
});
db.messages.createIndex({
internaldate: -1
});
db.messages.createIndex({
headerdate: 1
});
db.messages.createIndex({
headerdate: -1
});
db.messages.createIndex({
size: 1
});
db.messages.createIndex({
size: -1
});
db.messages.createIndex({
uid: 1
});
db.messages.createIndex({
uid: -1
});
db['attachments.files'].createIndex({
'metadata.messages': 1
});
db.journal.createIndex({
mailbox: 1,
modseq: 1
});
db.journal.createIndex({
mailbox: 1,
modseq: -1
});
db.journal.createIndex({
created: 1
}, {
expireAfterSeconds: 21600
});

103
indexes.json Normal file
View file

@ -0,0 +1,103 @@
[{
"collection": "users",
"indexes": [{
"name": "users",
"key": {
"username": 1
}
}]
}, {
"collection": "mailboxes",
"indexes": [{
"name": "user_mailboxes",
"key": {
"username": 1
}
}, {
"name": "user_subscribed",
"key": {
"username": 1,
"subscribed": 1
}
}, {
"name": "find_by_user",
"key": {
"username": 1,
"path": 1
}
}]
}, {
"collection": "messages",
"indexes": [{
"name": "mailbox_messages",
"key": {
"mailbox": 1
}
}, {
"name": "mailbox_uid_modseq",
"key": {
"mailbox": 1,
"uid": 1,
"modseq": 1
}
}, {
"name": "mailbox_flags",
"key": {
"mailbox": 1,
"flags": 1
}
}, {
"name": "by_modseq",
"key": {
"modseq": 1
}
}, {
"name": "by_flags",
"key": {
"flags": 1
}
}, {
"name": "by_internaldate",
"key": {
"internaldate": 1
}
}, {
"name": "by_headerdate",
"key": {
"headerdate": 1
}
}, {
"name": "by_size",
"key": {
"size": 1
}
}, {
"name": "by_uid",
"key": {
"uid": 1
}
}]
}, {
"collection": "attachment.files",
"indexes": [{
"name": "related_messages",
"key": {
"metadata.messages": 1
}
}]
}, {
"collection": "journal",
"indexes": [{
"name": "mailbox_modseq",
"key": {
"mailbox": 1,
"modseq": 1
}
}, {
"name": "autoexpire",
"expireAfterSeconds": "21600",
"key": {
"created": 1
}
}]
}]

View file

@ -2,10 +2,9 @@
"name": "wildduck",
"version": "1.0.4",
"description": "IMAP server built with Node.js and MongoDB",
"main": "index.js",
"main": "server.js",
"scripts": {
"test": "grunt",
"indexes": "mongo `node ./bin/mongo.js` indexes.js"
"test": "grunt"
},
"keywords": [],
"author": "Andris Reinman",