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 = [...]
  */
}
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
Initialize a new Application inherits from EventEmitter