fastboot-app-server icon indicating copy to clipboard operation
fastboot-app-server copied to clipboard

Option for cluster

Open medokin opened this issue 7 years ago • 4 comments

Can clustering be made optional?

Azure App Service for example, does not support node cluster.

medokin avatar Sep 30 '17 13:09 medokin

We had the same issue, PM2 doesn’t like clustering as it can’t see child processes.

We removed the cluster function and separated the notification in to a separate server, but it’s not perfect.

morgano86 avatar Oct 01 '17 10:10 morgano86

Same issue here using PM2.

williamweckl avatar Jun 15 '19 22:06 williamweckl

@morgano86 I know it is late, but in case anyone else needs it I was able to make it work with pm2.

I had to extract the notifier and downloader logic to a script outside the script that is executed by pm2 instances. That's because if I do not do that all instances would be downloading codes and it's not what we want I suppose.

startup.js:

const S3Downloader = require("fastboot-s3-downloader");
const S3Notifier = require("fastboot-s3-notifier");
const pm2 = require('pm2');

let downloader = new S3Downloader({
  ... // Your downloader bucket config goes here
});

let notifier = new S3Notifier({
  ... // Your notifier bucket config goes here
});

let UI = require('fastboot-app-server/src/ui');
const ui = new UI();
downloader.ui = ui;
notifier.ui = ui;

const startApp = function () {
  ui.writeLine('Starting APP');

  return pm2.connect(function(err) {
    if (err) {
      console.log(err);
      process.exit(2);
    }

    return pm2.start('ecosystem.config.js', function(err, apps) {
      pm2.disconnect(); // Disconnects from PM2
      if (err) throw err
    });
  });
};

const download = function() {
  ui.writeLine('Downloading APP');

  return downloader.download().then(function () {
    ui.writeLine('APP downloaded');
  });
}

const subscribeToNotifier = function() {
  ui.writeLine('Subscribing to update notifications');
  return notifier.subscribe(() => {
    ui.writeLine('Downloading new APP version');

    download().then(function () {
      ui.writeLine('Reloading apps');

      pm2.reload('YourAppName', function (err, proc) {
        if (err) {
          ui.writeError('Error reloading apps');
          console.log(err);
          console.log(proc);
        } else {
          ui.writeLine('Apps reloaded!');
        }
      });
    });
  }).catch(err => {
    ui.writeError('Error subscribing');
    console.log(err.stack);
  });
}

download().then(function () {
  startApp();
  subscribeToNotifier();
});

ecosystem.config.js

module.exports = {
  apps: [{
    name: "YourAppName",
    script: "./server.js",
    exec_mode: 'cluster',
    instances: "max",
    max_memory_restart: '300M',
    mergeLogs: true
  }]
}

server.js

const FastBootAppServer = require("fastboot-app-server");
const ExpressHTTPServer = require('fastboot-app-server/src/express-http-server');

const httpServer = new ExpressHTTPServer({
  gzip: true,
  chunkedResponse: true
});
const app = httpServer.app;
let server = new FastBootAppServer({
  httpServer: httpServer,
  distPath: 'dist',
  gzip: true,
  chunkedResponse: true // Optional - Opt-in to chunked transfer encoding, transferring the head, body and potential shoeboxes in separate chunks. Chunked transfer encoding should have a positive effect in particular when the app transfers a lot of data in the shoebox.
});

server.start();

The code is not so elegant, but it do the work without having to modify any fastboot-app-server library. Hope it helps someone ;)

williamweckl avatar Jun 16 '19 02:06 williamweckl

By the way, my servers are using much less memory after the modification ::D

williamweckl avatar Jun 16 '19 17:06 williamweckl