bun icon indicating copy to clipboard operation
bun copied to clipboard

Ability to unref timers (`setTimeout`, `setInterval`)

Open paperclover opened this issue 3 years ago • 4 comments

What is the problem this feature will solve?

Setting an interval that wont block the exiting of Bun is impossible, but is possible on Node and Deno.

There is currently no bun-equivilent of this node.js code:

const timer = setTimeout(() => {
  console.log('timeout');
}, 1000);
timer.unref(); // this will make node exit immediatly

What is the feature you are proposing to solve the problem?

copying either

What alternatives have you considered?

not having this feature, but it will subtly break some npm packages. i think discord.js uses this to sweep caches, but you usually have a network connection open so that would block the runtime's exit..

paperclover avatar Jul 26 '22 01:07 paperclover

I do think this needs to exist. I wanted to avoid a direct ref/unref API (like what web browsers do), but I think it's just not practical (i.e. buggy) to attempt to do it automatically all the time.

Jarred-Sumner avatar Jul 26 '22 02:07 Jarred-Sumner

I think we would be able to implement this with better feature parity with Node.js by returning a Number (class) instance that has been patched to include the unref() and ref(). The functions would simply utilize a Bun.unref() and Bun.ref() functions but allow for better interop because some Node.js code relies on these non-standard properties on the return of setTimeout / setInterval. The same could most likely be done for the other properties of the non-standard Interval and Timeout in node.

edit: I'd rather not include this in the types, though, because the web API is far better IMO

sno2 avatar Jul 30 '22 15:07 sno2

That's an incredibly hacky way of just abandoning your timeout as if it doesn't exist (which it does). Use clearTimeout to actually remove your timeout instead.

these perform different actions. an unref will call your callback when the timer happens, but timers will block the exit of your app. an unref timer in node will allow the app to exit but if something else keeps it open, the timer will still exist.

paperclover avatar Jul 30 '22 20:07 paperclover

If you import from node:timers this should work

Jarred-Sumner avatar Oct 27 '22 19:10 Jarred-Sumner

it doesn't seem to work in bun canary

import { test } from 'bun:test';
import { setTimeout } from 'node:timers';

test('unref is possible', () => {
  const timer = setTimeout(() => {}, 1000);
  timer.unref();
  clearTimeout(timer);
});

paperclover avatar Nov 17 '22 04:11 paperclover

clearTimeout / clearInterval etc works but the NodeJS Timeout object with unref() and ref() is not implemented.

Jarred-Sumner avatar Nov 17 '22 05:11 Jarred-Sumner

Fixed in https://github.com/oven-sh/bun/commit/2a1558e4d6fc2e7abbb9a6f4abc3cc4bb2d49c59

Jarred-Sumner avatar Feb 23 '23 03:02 Jarred-Sumner