I have tested the sample. (credit goes for the author on GitHub)
1, Usually NODE_ENV environment variable refers to development, production, staging, etc.
It can be anything (like "apple"), but the trick is that this "name" property refers to the "queue" name which has to be unique for each listener/subscriber.
2, Like I have noted above, this "name" property (outside of exchange object) is for the name of the queue. It has to be unique for each listener. Each listener will have it's own queue which is bind to the exchange.
3, It can be anything. But this is tricky as well.
For the client who will "publish" to the fanout exchange it needs to have the same pin in the options as the called action's pattern. For example if the client will call:
seneca.act('event:orderReceived', optionalPayload)
then the pin has to be:
{
pin: 'event:orderReceived',
...
}
See Seneca API docs for how patterns work.
For the listeners, in this case (for RPC this is not true) they don't have to match the pin. Only the pattern has to match when you call seneca.add function (little bit strange). For example:
seneca.add('event:orderReceived', function (msg, respond) {
// some logic
})
the pin property can be:
{
pin: 'something:different'
}
4, For the last question the answer is true, it can provide a publish/subscribe functionality. I have tested it.
Note that if you don't pass a callback to seneca.act when "publishing" to exchange, then it does not wait for any response. For example:
seneca.act('event:orderReceived', { some: "payload" })
Also note, that if you don't need a response, you will have to call the response callback with a null
for first (error) parameter anyway, in the listener service, otherwise it will timeout. See in the examples below.
Here is my version of the code:
Publisher
const seneca = require('seneca')
const si = seneca()
si
.use('seneca-amqp-transport')
.client({
type: 'amqp',
pin: 'event:orderReceived',
url: 'amqp://localhost:5672',
exchange: {
name: 'order-service',
type: 'fanout'
}
})
.ready( function() {
si.log.info('order-service application is running...')
si.act('event:orderReceived', {})
})
process.on('SIGTERM', () => {
si.log.info('Got SIGTERM. Graceful shutdown start')
si.act('role:seneca,cmd:close')
})
Subscriber 1
const seneca = require('seneca')
const si = seneca()
si
.use('seneca-amqp-transport')
.add('event:orderReceived', function(msg, respond) {
si.log.info(msg)
respond(null)
})
.listen({
type: 'amqp',
pin: 'some:pin1',
url: 'amqp://localhost:5672',
name: 'delivery-service-queue',
exchange: {
name: 'order-service',
type: 'fanout'
}
})
.ready( function() {
si.log.info('delivery-service application is running...')
})
process.on('SIGTERM', () => {
si.log.info('Got SIGTERM. Graceful shutdown start')
si.act('role:seneca,cmd:close')
})
Subscriber 2
const seneca = require('seneca')
const si = seneca()
si
.use('seneca-amqp-transport')
.add('event:orderReceived', function(msg, respond) {
si.log.info(msg)
respond(null)
})
.listen({
type: 'amqp',
pin: 'some:pin2',
url: 'amqp://localhost:5672',
name: 'financial-service-queue',
exchange: {
name: 'order-service',
type: 'fanout'
}
})
.ready( function() {
si.log.info('financial-service application is running...')
})
process.on('SIGTERM', () => {
si.log.info('Got SIGTERM. Graceful shutdown start')
si.act('role:seneca,cmd:close')
})
I am not sure that this is a proper way, but seems to work.