cote icon indicating copy to clipboard operation
cote copied to clipboard

Prevent responder from getting new requests

Open Nazar910 opened this issue 4 years ago • 5 comments

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. image 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.

Nazar910 avatar Sep 18 '20 09:09 Nazar910

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 avatar Sep 20 '20 14:09 dashersw

@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?

otothea avatar Nov 16 '20 18:11 otothea

I think there are two approaches:

  1. 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.
  2. 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 has shuttingDown: 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!

dashersw avatar Nov 17 '20 22:11 dashersw

Oh, and all of this could be implemented in cote.

dashersw avatar Nov 17 '20 22:11 dashersw

Is this taken care of? I would be happy to help.

rishi003 avatar Mar 09 '23 14:03 rishi003