tomas / needle

Nimble, streamable HTTP client for Node.js. With proxy, iconv, cookie, deflate & multipart support.
https://www.npmjs.com/package/needle
MIT License
1.63k stars 236 forks source link

Support for a global AbortController #297

Open walmat opened 4 years ago

walmat commented 4 years ago

I have a weird use case where I want to abort any and all needle requests when a user chooses to do so.

How I have it setup right now using node-fetch is I'm creating a default instance that patches in an AbortController signal, this in turn is used in every fetch call I make using this instance.

this._aborter = new AbortController();
this._fetch = defaults(_fetch, {
   timeout: 120000, // can be overridden as necessary per request
   signal: this._aborter.signal
});

It would be nice if needle supported something similar (if it already does I apologize as I couldn't find any documentation on it).

this._aborter = new AbortController();
this._needle = needle.defaults({
   timeout: 120000, // can be overridden as necessary per request
   signal: this._aborter.signal // <-- this being passed to the default config would allow any needle request to be cancelled when the signal is triggered.
});
JiPaix commented 4 years ago

I'm also interested in this, one dirty solution i found for now is:

having an event emitter:

const event = new events.EventEmitter()

wrap each request in a promise:

new Promise(function (resolve, reject) {
            needle.get('https://speed.hetzner.de/10GB.bin', options)
            event.on('stop', (reason) => {
                reject(reason + ' from #1')
            })
    }).catch(e => console.log(e))

new Promise(function (resolve, reject) {
        needle.get('https://speed.hetzner.de/10GB.bin', options)
        event.on('stop', (reason) => {
            reject(reason + ' from #2')
        })
}).catch(e => console.log(e))

and stop them later in the code:

setTimeout(() => {
    event.emit('stop', 'timeout')
}, 3000);
maapteh commented 3 years ago

Just like @walmat i also would like the signal option which we have as default in fetch libraries (node-fetch/axios/etc) on which we can put the abortController signal: AbortSignal. I don't want to hack around it. Some libraries gave a timeout option but the signal is more to spec. And i was surprised not to see it in this library. Will this feature land here?

tomas commented 3 years ago

Definitely yes. If someone can submit a PR it would be great. Otherwise I can try to look at this during the weekend.