Пример #1
0
const iforward = (n) => (b, p, o, cb) => {
  // Convert the period (# of days since Jan 1, 1970) to a YYYYMM date
  const t = new Date(p * 86400000);
  const m = t.getUTCFullYear() * 100 + t.getUTCMonth() + 1;

  // Use n partitions, one epoch per month, assume that each partition
  // supports all operations, and a single db per partition
  return cb(undefined, [
    [parseInt(vcapenv.appindex()), m]
  ]);
};
Пример #2
0
const seqid = () => {
  const t = moment.now();
  id = t <= id.t ? {
    t: id.t,
    c: id.c + 1
  } : {
    t: t,
    c: 0
  };
  return [pad16(id.t),
    vcapenv.appindex(), vcapenv.iindex(), cluster.wid(), id.c].join('-');
};
Пример #3
0
const worker = () => {
  debug('Cluster worker started');
  emitter.emit('log', {
    category: 'cluster',
    event: 'started',
    type: 'worker',
    pid: process.pid
  });

  // Set the worker process title
  process.title = 'node ' +
    (process.env.TITLE || [vcapenv.appname(), vcapenv.appindex()].join('-')) +
    ' worker';

  // Handle process signals
  signals('worker', (exitcb) => {
    // Let the process exit
    exitcb();
  });

  // Send a heartbeat message to the master at regular intervals
  // If the worker fails to send a heartbeat, well, we know it's not going
  // well and the master will terminate it
  const heartbeatReporter = setInterval(() => {
    process.send({
      heartbeat: Date.now()
    });
  }, heartbeatInterval);

  // Shutdown the heartbeat reporter when the worker is getting disconnected
  process.on('disconnect', () => {
    clearInterval(heartbeatReporter);
  });

  // Emit messages from the master to the emitter listeners
  process.on('message', (msg) => {
    emitter.emit('message', msg);
  });
};
Пример #4
0
const master = () => {
  debug('Cluster master started');
  emitter.emit('log', {
    category: 'cluster',
    event: 'started',
    type: 'master',
    pid: process.pid
  });

  // Monitor the heartbeats of our workers at regular intervals
  const i = setInterval(heartMonitor, heartMonitorInterval);
  if(i.unref) i.unref();

  // Set the master process title
  process.title = 'node ' +
    (process.env.TITLE || [vcapenv.appname(), vcapenv.appindex()].join('-')) +
    ' master';

  // Handle process signals
  signals('master', (exitcb) => {
    // Terminate the workers

    // Let the master process exit
    exitcb();
  });

  // Restart worker on disconnect unless it's marked with a noretry flag
  cluster.on('disconnect', (worker) => {
    edebug('Cluster worker %d disconnected', worker.process.pid);
    debug('Cluster worker %d disconnected', worker.process.pid);
    if(!worker.noretry) {
      edebug('Restarting cluster worker');
      monitor(cluster.fork());
    }
  });

  cluster.on('exit', (worker, code, signal) => {
    edebug('Cluster worker %d exited with code %d', worker.process.pid, code);
    debug('Cluster worker %d exited with code %d', worker.process.pid, code);
  });

  // Handle messages from worker servers
  emitter.on('message', (msg) => {
    if(msg.server) {
      if(msg.server.noretry) {
        debug('Cluster worker %d reported fatal error',
          msg.worker.process.pid);
        edebug('Cluster worker %d reported fatal error',
          msg.worker.process.pid);

        // Mark worker with a noretry flag if it requested it, typically to
        // avoid infinite retries when the worker has determined that retrying
        // would fail again anyway
        // Warning: mutating worker variable here
        cluster.workers[msg.worker.id].noretry = true;
      }

      if(msg.server.listening)
        debug('Cluster worker %d listening on %d',
          msg.worker.process.pid, msg.server.listening);

      if(msg.server.exiting)
        debug('Cluster worker %d exiting', msg.worker.process.pid);
    }
  });
};
Пример #5
0
const listen = function(opt) {
  const app = this;

  // Configure the listen options
  const conf = lconf(opt);

  // Set the process title
  process.title = 'node ' +
    (process.env.TITLE || [vcapenv.appname(), vcapenv.appindex()].join('-')) +
    ' express';

  app.use(catchall());

  if(!app.basic) {
    // Register some of our middleware after the routes
    app.use(sendValue());
    app.use(options());

    // Register debug config middleware
    if(process.env.SECURED === 'true')
      app.use('/debug',
        oauth.validator(process.env.JWTKEY, process.env.JWTALGO));
    app.use('/debug', cdebug());

    // Serve public static resources under the app public dir as well as this
    // module's public dir
    app.use(statics(path.join(process.cwd(), 'public')));
    app.use(statics(path.join(__dirname, 'public')));
  }

  // Catch 404 errors
  app.use((req, res, next) => {
    res.status(404).send({
      error: 'notfound',
      message: 'Not found'
    });
  });

  // Create an HTTP or HTTPS server
  const server = conf.key && conf.cert ? https.createServer({
    key: conf.key,
    cert: conf.cert
  }, app) : http.createServer(app);

  // Handle middleware errors
  app.use(uncaught((err) => {

    // This will be invoked if the err has a bailout flag
    return bailout(err, server, true);
  }));

  // Listen on the configured port
  server.on('error', (err) => {
    // Signal that we encountered a no-retryable error
    emitter.emit('message', {
      server: {
        noretry: err
      }
    });

    edebug('Server error %o', err);
    debug('Server error %o', err);
    return bailout(err, server, false);
  });

  // Log HTTP ugrades to Web sockets
  server.on('upgrade', (req, socket, head) => {
    debug('Server upgrade request %s', req.url);
  });

  // Listen on the configured port
  server.listen(conf.port, conf.hostname, undefined, () => {
    debug('Server listening on %d', server.address().port);

    // Signal that we're listening
    emitter.emit('message', {
      server: {
        listening: server.address().port
      }
    });
  });

  // Return the server we're using
  return server;
};