cote
cote copied to clipboard
Prevent responder from getting new requests
Hi, I'm working on my service to graceful shutdown. How can I prevent responder to accept new requests so it could finish already got ones and then call responder.close
?
I have example responder:
const cote = require('cote');
const { SHOULD_SIGTERM } = process.env;
async function main() {
const server = new cote.Responder({
name: 'rpc-server',
namespace: 'rpc-server',
key : 'rpc-server'
});
server.on('foo', async ({ type, data }) => {
const { i } = data;
if (SHOULD_SIGTERM && i === 5) {
server.close();
}
console.log('Data', i);
const result = `bar-${i}`;
console.log('Result', result);
return result;
})
}
if (require.main === module) {
main();
}
and example requester that make 10 requests:
const cote = require('cote');
async function main() {
const requester = new cote.Requester({
name: 'rpc-requester',
namespace: 'rpc-server',
key: 'rpc-server',
});
for (let i = 0; i < 10; i++) {
let result;
try {
result = await requester.send({
type: 'foo',
data: {
i,
},
__timeout: 3 * 1000
});
} catch (e) {
console.error(e);
}
console.log('Result', result);
}
requester.close();
}
if (require.main === module) {
main();
}
As I coded responder to close on request with i === 5
, I lose this request. IMPORTANT NOTE: when I do NOT specify __timeout
in requester, once responder is restarted this request hangs forever.
In case when I do NOT call
responder.close
untill all requests are processed I keep getting new requests, so it does not seems like a solution.
Thanks in advance.
This is a good question. cote currently doesn't support graceful shutdowns, we should add it as a feature. Would you be intrerested in doing it?
@dashersw I am interested in adding this feature as well. Can you explain to me the best approach to this and I can try to implement? Is this solved in cote or node-discover?
I think there are two approaches:
- Do
this.discovery.stop
on the responder so that first we block new incoming requesters from discovering us and connecting to us, and then modify every response we are sending out to inject a property such as "stop asking" so that every requester that we are still connected stops sending us requests, and potentially, disconnect from us. when there are no more requesters connected to us, we can safely exit. - modify the
advertisement
object of the responder to add a property such as "i'm exiting so don't connect to me and also disconnect from me if you are connected." when a requester finds this service that hasshuttingDown: true
in its advertisement, they refrain from connecting. and another requester which was already connected to the responder who get these advertisements stop sending messages to them.
both are similar, the first one would be much quicker in terms of execution, the second one would make you wait ~ 3-5 seconds for the discovery mechanism to work. the first one has the downside of augmenting / modifying the client's response object. I don't know however problematic that would be, especially if we strip those messages on the requester before we hand it over to the user's actual callback. Hope this helps!
Oh, and all of this could be implemented in cote.
Is this taken care of? I would be happy to help.