Example #1
0
  channelManager.findOrCreateConsumer = function (topic, options) {
    let channel = consumersByTopic[topic];
    if (channel) return channel;

    let isServiceChannel = (topic[0] === "_");
    channel = consumersByTopic[topic] = new EventEmitter();
    channel.raw = channelManager.createRawConsumer(topic, options);
    channel.setMaxListeners(0);

    let autoConfirm;
    if (options && "autoConfirm" in options) {
      autoConfirm = options.autoConfirm;
    } else {
      autoConfirm = adapterConfig && adapterConfig.autoConfirm;
    }

    // TODO: is it ok to add custom methods to EventEmitter?
    channel.onceConsuming = (channel.raw.onceConsuming) ? function (cb) {
      channel.raw.onceConsuming(cb);
      return channel;
    } : noopCb;

    channel.rejectMessage = (channel.raw.rejectMessage) ? function (message) {
      channel.raw.rejectMessage(message);
    } : noop__;

    channel.confirmProcessedMessage = (channel.raw.confirmProcessedMessage) ? function (message, _safe) {
      // Only use _safe if you can"t know whether message has already been confirmed/rejected
      channel.raw.confirmProcessedMessage(message, _safe);
    } : noop__;

    function onMessage(message) {
      if (messageHasExpired(message)) {
        channel.rejectMessage(message);
        return;
      }
      channelManager.emit(channelManager.CONSUMER_NEW_MESSAGE_EVENT, topic);

      // TODO: emit custom object rather than instance of EventEmitter
      channel.emit("message", message, channel);

      if (autoConfirm) channel.confirmProcessedMessage(message, true);
    }

    function onValidationError(err, message) {
      channel.rejectMessage(message);
    }

    // Validate with envelope schema
    if (!isServiceChannel && config.schema) {
      channel.raw.on("message", validateWithSchema.onEvent(config.schema, onMessage, onValidationError));
    } else {
      channel.raw.on("message", onMessage);
    }

    channel.on("error", function (err, message) {
      if (autoConfirm && message) {
        // Reject when a message has generated an error, e.g. not validated
        channel.rejectMessage(message);
      }
    });

    channel.raw.on("error", channel.emit.bind(channel, "error")); // TODO: wtf?

    // channel.raw.on("consuming", channel.emit("consuming"));

    channelManager.emit(channelManager.CONSUMER_NEW_TOPIC_EVENT, topic);

    if (isServiceChannel || !config.cleanupConsumers) return channel;

    channel.on("removeListener", function (eventName) {
      if (eventName !== "message") return;
      if (consumerTopicsToCheck.indexOf(topic) > -1 || channel.listeners(eventName).length) return;
      consumerTopicsToCheck.push(topic);

      if (consumerTopicsToCheck.length > 1) return;
      setImmediate(checkConsumers);
    });

    return channel;
  };