Search code examples
node.jsmongoosenode-cluster

Moongose not connecting to DB in a cluster node


I have a setup with a clustered nodejs app (1 Master and 4 Workers).

The master instantiate the workers and create a bunch of tasks that they can grab.

Each worker initiate a DB connection like this :

import Database from './db';

//Worker
class Worker {
  constructor(process) {
    this.process = process;
    this.id = process.pid;

    this.db = new Database();
    console.log('[Worker][', this.id, '][Init] Ready');

    this.process.on('message', this.onMessage.bind(this));
  }

  onMessage(msg) {
     this.task = msg.task;
     new Task(this.task, this.db);
  }
}

My Database class looks like this :

import mongoose from 'mongoose';
import bluebird from 'bluebird';
import config from '../server/config/config.json';
import MyModel from '../server/model/mymodel';

class Database {
    constructor() {
        this.db = config.db;
        this.connect();
    }

    connect() {
        mongoose.Promise = bluebird;

        mongoose
            .connect(this.db.uri, {
                user: this.db.user,
                pass: this.db.pass,
                auth: {
                    authdb: this.db.authdb
                },
                promiseLibrary: bluebird,
                autoIndex: true,
                reconnectTries: Number.MAX_VALUE,
                reconnectInterval: 500,
                poolSize: 10,
                bufferMaxEntries: 0
            })
            .then(() => {
                console.log('connected');
            })
            .catch(err => {
                console.log(err);
                );
            });
    }

    async save(prices) {
        if (prices) {
            try {
                let bulkUpdate = MyModel.collection.initializeUnorderedBulkOp();
                //bulkUpdate is UNDEFINED !!!

                prices.forEach(price => {
                    bulkUpdate
                        .find({ price: price })
                        .upsert()
                        .updateOne(price);
                });

                await bulkUpdate.execute();
            } catch (err) {
                console.log(err);
            }
        }
        else {
            console.log('[Worker] No prices provided to save.');
        }
    }
}

And my Task class :

class Task {
    constructor(url, db) {
        this.url = url;
        this.db = db;
    }

    onDataReceived(prices) {
        if (prices) {
            try {
                this.db.save(prices);
            }
            catch (err) {
                console.log('Could not save data.');
                console.log(err);
            }
        }
        else {
            console.log('No data received');
            return;
        }
    }
}

When I execute the code, the bulkUpdate variable is undefined after the initializeUnorderedBulkOp() thus I can't execute a .find() on it.

After doing some research, it seems that moongose might not be connected yet. The thing is that I have the console log console.log('connected'); before the initializeUnorderedBulkOp() being executed, so I think it is connected.

My question is, where is the catch? Does the fact of using clusters mess up with mongoose or the way I initialize it?

Thanks


Solution

  • Ok so I found the issue, it had nothing to do with the way I organized the clusters nor mongoose itself.

    I was setting up the cluster App as its own package.json, and for some reason it was using the main app 'mongoose' package. So I deleted the 'mongoose' entry in the cluster package.json, and everything works fine...

    I still have no clue why it was breaking mongoose (double import?).