function (key, task, done, ttl) {
    const queue     = this.queue;
    const semaphore = this.semaphore;

    if (!ttl) ttl = this.ttl;


    const runTask = (res) => new Promise((resolve) =>
      task( (...args) => resolve(Response.setData(res, args)) )
    );


    const startThenRunTask = (lock_key) =>
      queue.start(key, Response.factory(ttl))
      .then(runTask)
      .then(queue.dequeue.bind(null, key))
      .then(() => semaphore.release(key, lock_key))
      .catch((err) => {
        semaphore.release(key, lock_key);
        throw err;
      })
    ;


    const startIfNotWaiting = () =>
      Promise.all([
        queue.isWaiting(key)
      , semaphore.lock(key)
      ])
      .then(([ is_waiting, lock_key ]) =>
        (!is_waiting && lock_key) ? startThenRunTask(lock_key) : null
      )

    return queue
      .add(key, done)
      .then(startIfNotWaiting)
    ;
  }
function (key, task, done, ttl) {
    const queue     = this.queue;
    const semaphore = this.semaphore;

    if (!ttl) ttl = this.ttl;


    const runTask = (res) => new Promise((resolve) =>
      task( (...args) => resolve(Response.setData(res, args)) )
    );


    const startThenRunTask = (lock_key) =>
      queue.start(key, Response.factory(ttl))
      .then(runTask)
      .then(queue.dequeue.bind(null, key))
      .then(() => semaphore.release(key, lock_key))
      .catch((err) => {
        semaphore.release(key, lock_key);
        throw err;
      })
    ;


    const startIfNotWaiting = () =>
      Promise.all([
        queue.isWaiting(key)
      , semaphore.lock(key)
      ])
      .then(([ is_waiting, lock_key ]) =>
        (!is_waiting && lock_key) ? startThenRunTask(lock_key) : null
      )

    return queue
      .add(key, done)
      .then(startIfNotWaiting)
    ;
  }
function ( key , task , done , ttl ) { const queue = this . queue ; const semaphore = this . semaphore ; if ( ! ttl ) ttl = this . ttl ; const runTask = ( res ) => new Promise ( ( resolve ) => task ( ( ... args ) => resolve ( Response . setData ( res , args ) ) ) ) ; const startThenRunTask = ( lock_key ) => queue . start ( key , Response . factory ( ttl ) ) . then ( runTask ) . then ( queue . dequeue . bind ( null , key ) ) . then ( ( ) => semaphore . release ( key , lock_key ) ) . catch ( ( err ) => { semaphore . release ( key , lock_key ) ; throw err ; } ) ; const startIfNotWaiting = ( ) => Promise . all ( [ queue . isWaiting ( key ) , semaphore . lock ( key ) ] ) . then ( ( [ is_waiting , lock_key ] ) => ( ! is_waiting && lock_key ) ? startThenRunTask ( lock_key ) : null ) return queue . add ( key , done ) . then ( startIfNotWaiting ) ; }
Queue up the given task using the given key as an identifier. @param {string} key @param {Function} task @param {Function} done @param {number} ttl - the time to live for the queue cache. @return {Queue}
Queue up the given task using the given key as an identifier .