docs: function Q(redis, preopts) {
    // handle forgetting a 'new'
    if (!(this instanceof Q)) {
      return new Q(redis, preopts);
    }
  
    if (preopts === undefined) preopts = redis, redis = preopts.redis;
  
    if (!redis && preopts.createRedis) {
      this._redis = redis = preopts.createRedis()
    } else {
      console.error('WARNING: passing a redis instance to relyq is deprecated. Please pass options.createRedis() function.')
      this._redis = redis
    }
  
    this._options = typeof preopts === 'string' ? {prefix: preopts, redis: redis} : preopts
    this._delimeter = preopts.delimeter || ':';
  
    this._idfield = preopts.idfield || 'id';
    this._prefix = preopts.prefix || preopts;
    this._clean_finish = preopts.clean_finish === undefined || preopts.clean_finish;
    this._keep_storage = preopts.clean_finish === 'keep_storage';
  
    this.todo = new simpleq.Q(redis, this._prefix + this._delimeter + 'todo');
    this.doing = new simpleq.Q(redis, this._prefix + this._delimeter + 'doing');
    this.failed = new simpleq.Q(redis, this._prefix + this._delimeter + 'failed');
    if (!this._clean_finish) {
      this.done = new simpleq.Q(redis, this._prefix + this._delimeter + 'done');
    }
  
    if (preopts.allow_defer && preopts.createRedis) {
      this.deferred = new DeferredTaskList(this, {
        polling_interval: preopts.defer_polling_interval,
        key: this._prefix + this._delimeter + 'deferred',
        redis: preopts.createRedis(),
      });
    }
    if (preopts.allow_recur && preopts.createRedis) {
      this.recurring = new RecurringTaskList(this, {
        polling_interval: preopts.recur_polling_interval,
        key: this._prefix + this._delimeter + 'recurring',
        redis: preopts.createRedis(),
      });
    }
  
    EventEmitter.call(this);
  
    var rq = this;
    if (this._redis.ready) {
      setImmediate(function () {
        rq.emit('ready')
      })
    } else {
      this._redis.once('ready', function () {
        rq.emit('ready')
      })
    }
  }