moleculerjs / moleculer

:rocket: Progressive microservices framework for Node.js
https://moleculer.services/
MIT License
6.13k stars 580 forks source link

Inconsistent behavior of 'emit' #284

Closed jedrzej-bridgemaker closed 1 year ago

jedrzej-bridgemaker commented 6 years ago

Hi.

I've noticed some weird behaviour when using moleculer with AMQP (rabbitMQ) and disabled balancer.

Steps to reproduce

  1. Have service A emit an event and service B listen to that event.
  2. Start service B
  3. Start service A
  4. Stop service B
  5. Make service A emit a couple of events
  6. Start a second instance of service A and make it also emit a couple of events
  7. Start service B

Current Behavior

Only events from the first instance of service A, which have been emitted while service B was offline are consumed. Events from the second instance of A are ignored.

Expected Behavior

Events from both instances are treated the same way.

The problem is I can't tell what should be the expected behavior, whether both instances should push their events to the appropriate queue or neither. I'd suggest that if Service B quit unexpectedly, then both instances of service A should send their messages. Otherwise neither should.

Reproduce code snippet

//Service A
const broker = new ServiceBroker({
    logger: console,
    transporter: "AMQP",
    disableBalancer: true
});

broker.createService({
    name: "Service A"
});

broker.start().then(() => setInterval(() => broker.emit('hello', { pid: process.pid}), 1000))

//Service B
const broker = new ServiceBroker({
    logger: console,
    transporter: "AMQP",
    disableBalancer: true
});

broker.createService({
    name: "Service B",
    events: {
        hello: ({ pid }) => console.log('Received hello message from process:', pid)
    }
});

Context

[This is related to #83 I think]

rmccallum81 commented 6 years ago

I think this would be expected as the second Service A does not have a Service B registered. The only way around this is to have emitted events stored for future consumption if no registered services are listening for that event.

If the heartbeat timeout passes before Service B is restarted, then neither would send an event. Currently the first Service A is retying while Service B is unavailable which is why it does get sent after it restarts.