zx icon indicating copy to clipboard operation
zx copied to clipboard

Feature: Abort controller support

Open vitalics opened this issue 3 years ago • 5 comments

As a part of node.js 16. Abort signal stable feature. I would like to propose Abort signal and Abort Controller support.

API:

import { $ } from 'zx';
const controller = new AbortController();

$('some long command', {signal: controller.signal});

if(somethingHapens){ // e.g. ctrl+c
controller.abort();
}
// some long command will be halted.

vitalics avatar Oct 10 '22 08:10 vitalics

What about kill() method? It already works.

antonmedv avatar Oct 10 '22 11:10 antonmedv

yes, that's worked, but the reason is resources. When signal comes for promises, it's not stops actually. and resources are not flushed. I mean what's happens when do the snippet:

function delay(ms: number){
	return new Promise(res => setTimeout(res, ms)})
}

await Promise.race([
delay(1000),
asyncFnLessThan1000ms(),
])

set timeout will not stops actually, results will be ignored (it takes machine time)

But if we use the signal to stop any async code(setTimeout in this case) - nodejs will real stop setTimeout fn and flush resources.

The same behavior for the child process, This feature will reduce process memory/time management

vitalics avatar Oct 10 '22 13:10 vitalics

Native intertop with signal would make the API a lot nicer to use.

Now the API feels awkward:

handle: async ({ signal }) => {
  const promise = $`sleep 30`;

  const kill = () => {
    promise.kill();
  };

  signal.addEventListener('abort', kill, { once: true });

  await promise;

  signal.removeEventListener('abort', kill);
},

If zx added native support, it could be simplified down to:

handle: async ({ signal }) => {
  await $({signal})`sleep 30`;
},

This API is similar to how sql.type() is used in Slonik, example.

gajus avatar Feb 24 '23 12:02 gajus

Please show an example with usage with signal vs kill()

antonmedv avatar Feb 24 '23 12:02 antonmedv

Updated

gajus avatar Feb 24 '23 15:02 gajus