<commit_before>'use strict';


const { resolve } = require('path');
const { cloneDeep } = require('lodash');

const { Log } = require('../logging');
const { processErrorHandler } = require('./process');
const { processOptions } = require('../options');
const { getIdl } = require('../idl');
const { ApiEngineServer } = require('./api_server');
const { getMiddleware } = require('./middleware');
const { httpStartServer } = require('./http');
const { setupGracefulExit } = require('./exit');
const { handleStartupError } = require('./startup_error');


// Used e.g. to shorten stack traces
global.apiEngineDirName = resolve(__dirname, '../..');

/**
 * Start server for each protocol, for the moment only HTTP
 *
 * @param {object} options
 * @param {object} options.idl - IDL definitions
 */
const startServer = function (options = {}) {
  const apiServer = new ApiEngineServer();
  const startupLog = new Log({ opts: options, phase: 'startup' });

  start(options, apiServer, startupLog)
  .catch(error => handleStartupError(options, apiServer, error));

  return apiServer;
};

const start = async function (options, apiServer, startupLog) {
  const allPerf = startupLog.perf.start('all', 'all');
  const perf = startupLog.perf.start('main');

  const originalOptions = cloneDeep(options);

  const processLog = processErrorHandler({ opts: options });
  // Assign them to `options` so they are easily available anywhere
  Object.assign(options, { apiServer, startupLog, processLog });

  perf.stop();
  const opts = await processOptions(options);
  opts.idl = await getIdl({ opts });

  // Those two callbacks must be called by each server
  opts.handleRequest = await getMiddleware(opts);

  const serversPerf = startupLog.perf.start('servers');
  opts.handleListening = handleListening.bind(null, startupLog);

  // Start each server
  const httpPerf = startupLog.perf.start('HTTP', 'server');
  const httpServer = httpStartServer(opts);
  httpServer.then(() => httpPerf.stop());

  // Make sure all servers are starting concurrently, not serially
  const serversArray = await Promise.all([httpServer]);
  const [http] = serversArray;
  serversPerf.stop();
  perf.start();

  const servers = { http };
  Object.assign(apiServer, { servers, options: originalOptions });

  setupGracefulExit({ servers: serversArray, opts });

  // Create log message when all protocol-specific servers have started
  startupLog.log('Server is ready', { type: 'start' });
  await apiServer.emitAsync('start');

  perf.stop();
  allPerf.stop();
  await startupLog.perf.report();
};<commit_msg>Emit event 'start' before logging it<commit_after>'use strict';


const { resolve } = require('path');
const { cloneDeep } = require('lodash');

const { Log } = require('../logging');
const { processErrorHandler } = require('./process');
const { processOptions } = require('../options');
const { getIdl } = require('../idl');
const { ApiEngineServer } = require('./api_server');
const { getMiddleware } = require('./middleware');
const { httpStartServer } = require('./http');
const { setupGracefulExit } = require('./exit');
const { handleStartupError } = require('./startup_error');


// Used e.g. to shorten stack traces
global.apiEngineDirName = resolve(__dirname, '../..');

/**
 * Start server for each protocol, for the moment only HTTP
 *
 * @param {object} options
 * @param {object} options.idl - IDL definitions
 */
const startServer = function (options = {}) {
  const apiServer = new ApiEngineServer();
  const startupLog = new Log({ opts: options, phase: 'startup' });

  start(options, apiServer, startupLog)
  .catch(error => handleStartupError(options, apiServer, error));

  return apiServer;
};

const start = async function (options, apiServer, startupLog) {
  const allPerf = startupLog.perf.start('all', 'all');
  const perf = startupLog.perf.start('main');

  const originalOptions = cloneDeep(options);

  const processLog = processErrorHandler({ opts: options });
  // Assign them to `options` so they are easily available anywhere
  Object.assign(options, { apiServer, startupLog, processLog });

  perf.stop();
  const opts = await processOptions(options);
  opts.idl = await getIdl({ opts });

  // Those two callbacks must be called by each server
  opts.handleRequest = await getMiddleware(opts);

  const serversPerf = startupLog.perf.start('servers');
  opts.handleListening = handleListening.bind(null, startupLog);

  // Start each server
  const httpPerf = startupLog.perf.start('HTTP', 'server');
  const httpServer = httpStartServer(opts);
  httpServer.then(() => httpPerf.stop());

  // Make sure all servers are starting concurrently, not serially
  const serversArray = await Promise.all([httpServer]);
  const [http] = serversArray;
  serversPerf.stop();
  perf.start();

  const servers = { http };
  Object.assign(apiServer, { servers, options: originalOptions });

  setupGracefulExit({ servers: serversArray, opts });

  await apiServer.emitAsync('start');
  // Create log message when all protocol-specific servers have started
  startupLog.log('Server is ready', { type: 'start' });

  perf.stop();
  allPerf.stop();
  await startupLog.perf.report();
};
{'fraction_non_alphanumeric': 0.14757581610971604, 'fraction_numerical': 0.0, 'mean_word_length': 4.532051282051282, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4583811', 'n_tokens_mistral': 1478, 'n_tokens_neox': 1460, 'n_words': 425}