lib/application.js
function Application (options) {
  if (!(this instanceof Application)) return new Application(options)
  EventEmitter.call(this)
  // options defaults
  const env = getEnv()
  const COWORKERS_CLUSTER = env.COWORKERS_CLUSTER
  const COWORKERS_QUEUE = env.COWORKERS_QUEUE
  const COWORKERS_QUEUE_WORKER_NUM = env.COWORKERS_QUEUE_WORKER_NUM || 1
  options = options || {}
  // hack: instanceof check while avoiding rabbitmq-schema dep (for now)
  if (options.constructor.name === 'Schema') {
    options = { schema: options }
  }
  defaults(options, {
    cluster: COWORKERS_CLUSTER,
    queueName: COWORKERS_QUEUE,
    queueWorkerNum: COWORKERS_QUEUE_WORKER_NUM
  })
  defaults(options, {
    cluster: true
  })
  // set options on app
  this.schema = options.schema
  this.queueName = options.queueName
  this.queueWorkerNum = options.queueWorkerNum
  // validate options
  if (options.cluster && cluster.isMaster) {
    this.clusterManager = new ClusterManager(this)
    if (exists(options.queueName)) {
      console.warn('warn: "queueName" is not required when clustering is enabled')
    }
  } else {
    assert(exists(options.queueName), '"queueName" is required for consumer processes')
  }
  // app properties
  this.context = {}
  this.middlewares = []
  this.queueMiddlewares = {
    // <queueName>: [middlewares...]
  }
  Object.defineProperty(this, 'queueNames', {
    get () {
      return Object.keys(this.queueMiddlewares)
    }
  })
  /*
  this.connection = <amqplibConnection>
  this.consumerChannel = <amqplibChannel>
  this.publisherChannel = <amqplibChannel>
  this.consumerTags = [...]
  */
}
function Application (options) {
  if (!(this instanceof Application)) return new Application(options)
  EventEmitter.call(this)
  // options defaults
  const env = getEnv()
  const COWORKERS_CLUSTER = env.COWORKERS_CLUSTER
  const COWORKERS_QUEUE = env.COWORKERS_QUEUE
  const COWORKERS_QUEUE_WORKER_NUM = env.COWORKERS_QUEUE_WORKER_NUM || 1
  options = options || {}
  // hack: instanceof check while avoiding rabbitmq-schema dep (for now)
  if (options.constructor.name === 'Schema') {
    options = { schema: options }
  }
  defaults(options, {
    cluster: COWORKERS_CLUSTER,
    queueName: COWORKERS_QUEUE,
    queueWorkerNum: COWORKERS_QUEUE_WORKER_NUM
  })
  defaults(options, {
    cluster: true
  })
  // set options on app
  this.schema = options.schema
  this.queueName = options.queueName
  this.queueWorkerNum = options.queueWorkerNum
  // validate options
  if (options.cluster && cluster.isMaster) {
    this.clusterManager = new ClusterManager(this)
    if (exists(options.queueName)) {
      console.warn('warn: "queueName" is not required when clustering is enabled')
    }
  } else {
    assert(exists(options.queueName), '"queueName" is required for consumer processes')
  }
  // app properties
  this.context = {}
  this.middlewares = []
  this.queueMiddlewares = {
    // <queueName>: [middlewares...]
  }
  Object.defineProperty(this, 'queueNames', {
    get () {
      return Object.keys(this.queueMiddlewares)
    }
  })
  /*
  this.connection = <amqplibConnection>
  this.consumerChannel = <amqplibChannel>
  this.publisherChannel = <amqplibChannel>
  this.consumerTags = [...]
  */
}
Initialize a new `Application` inherits from EventEmitter
@constructor
@param  {Object|RabbitSchema} [options|schema] coworkers application options or rabbitmq schema
@param  {RabbitSchema} [options.schema] a RabbitMQ schema created by https://npmjs.com/rabbitmq-schema, optional
@param  {Boolean} [options.cluster] whether to use clustering or not
@param  {String} [options.queueName] queue name which this application is consuming
@api public