run(chain, args, callback, callbackContext) {
    if (this.running >= this.maxConcurrent) {
      if (this.buffer.length >= this.maxBufferSize) {
        callback.call(callbackContext, kerror.get("too_many_pipes"));
      } else {
        this.buffer.push(new PipeChain(chain, args, callback, callbackContext));
      }

      return;
    }

    this.running++;

    // Create a context for the waterfall callback
    const waterfallCallbackCtx = {
      callback,
      callbackContext,
      instance: this,
    };

    waterfall(chain, args, waterfallCallback, waterfallCallbackCtx);
  }
@warning Critical code section

Pipes can be run thousands of times per seconds
@param {Array} chain - functions chain
@param {Array} args  - functions arguments
@param {Function} callback - end-of-chain callback
@param {Object} callbackContext - functions/callback context