From efae1fb91e4085cec04a0eb0ca41fba9393b51f7 Mon Sep 17 00:00:00 2001 From: Andris Reinman Date: Mon, 20 Mar 2017 23:19:25 +0200 Subject: [PATCH] autoensure indexes when starting app --- README.md | 18 +-------- bin/mongo.js | 4 -- imap.js | 61 +++++++++++++++++++----------- indexes.js | 100 ------------------------------------------------- indexes.json | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +-- 6 files changed, 145 insertions(+), 146 deletions(-) delete mode 100644 bin/mongo.js delete mode 100644 indexes.js create mode 100644 indexes.json diff --git a/README.md b/README.md index 2140c017..33b4547b 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/bin/mongo.js b/bin/mongo.js deleted file mode 100644 index 4a7aa293..00000000 --- a/bin/mongo.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict'; -// reveal mongodb settings based on current environment -const config = require('config'); -process.stdout.write(config.mongo); diff --git a/imap.js b/imap.js index 5b3af32f..055978b3 100644 --- a/imap.js +++ b/imap.js @@ -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(); }); }; diff --git a/indexes.js b/indexes.js deleted file mode 100644 index 09e5635e..00000000 --- a/indexes.js +++ /dev/null @@ -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 -}); diff --git a/indexes.json b/indexes.json new file mode 100644 index 00000000..79bb76cf --- /dev/null +++ b/indexes.json @@ -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 + } + }] +}] diff --git a/package.json b/package.json index 6458bb41..cdc32201 100644 --- a/package.json +++ b/package.json @@ -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",