moleculer icon indicating copy to clipboard operation
moleculer copied to clipboard

Emit always event (configurable)

Open al66 opened this issue 4 years ago • 2 comments

Hi,

I have developed a mixed transporter imicros-transporter:

  • actions/responses and registry messages non-persistent via NATS
  • events persistent via kafka

Now I need to achieve that an event is always emitted - also if the subscribing service is down or no one is listening at all.

The current version of the service broker doesn't emit if no group is listening:

class ServiceBroker {
...
	emit(eventName, payload, opts) {
...
			if (groups.length == 0)
				return this.Promise.resolve();

** My Feature Request ** Is it possible to make this configurable somehow via a broker setting, that the event is always emitted?

** My workarround ** Not very nice... I register a dummy group via an addtional middleware:

module.exports ={

    // When event is emitted
    emit(next) {
        return async function emitter(eventName, payload, opts) {            

            // add dummy to force event emitting - also if there is no one listening
            await this.broker.registry.events.add(this.broker.nodeID, "global", { name: eventName, group: "global" });

            // Call default handler
            return next(eventName, payload, opts);
        };
    },
    
    created(broker) {
        this.broker = broker;
    }
  
};

al66 avatar Jul 05 '20 15:07 al66

There is no option because ServiceBroker sends the event to the listener nodes. If no group, no listener, it sends nowhere. In the case of disabledBalancer: true, it always sends the event to the transporter, because transporter does the balancing. For persisting, a better option if you save the event in the emit hook in middleware.

icebob avatar Jul 06 '20 09:07 icebob

Hi Icebob,

But that is the point. Also if disableBalancer:true it NOT always sends the event to the transporter. There comes first the check, if there is a group listening.

Persisting at all works fine with this transporter solution. Saving it in the emit hook is not an option as I want to use your really nice event subscription/handling in the service:

        await kafka.createService({
            name: "events",
            events: {
                "account.created": {
                    group: "worker",
                    handler(ctx) {
                        received++;
                        calls[this.broker.nodeID] ? calls[this.broker.nodeID]++ : calls[this.broker.nodeID] = 1;
                        this.logger.info("Event received, parameters OK!", ctx.params);
                    }
                }
            }
        });

al66 avatar Jul 06 '20 10:07 al66

@icebob can we consider this problem solved in moleculer-channels and coming out of the moleculer scope?

intech avatar Oct 10 '22 23:10 intech

Yeah, I think it can work with moleculer-channel but won't work with moleculer events.

icebob avatar Oct 12 '22 16:10 icebob