Skip to content

wasm: round sleepTicks up to a whole millisecond - #5818

Open
joeblew999 wants to merge 1 commit into
tinygo-org:devfrom
joeblew999:wasm-sleepticks-whole-ms
Open

joeblew999 wants to merge 1 commit into
tinygo-org:devfrom
joeblew999:wasm-sleepticks-whole-ms

Conversation

@joeblew999

Copy link
Copy Markdown

Fixes #5798.

The problem. On Cloudflare Workers (production, not local workerd) the clock only advances by a timer's delay rounded down to a whole millisecond. sleepTicks passes a fractional delay to setTimeout, so when less than a millisecond is left the scheduler re-arms a timer that never moves the clock, and Go timers (time.Sleep, time.Timer, context deadlines) stall until some other I/O happens.

The change. One line in targets/wasm_exec.js: Math.ceil on the delay. A sleep can end up to a millisecond late, which setTimeout never promised to beat anyway.

Measured. An HTTP API on Cloudflare Workers, built with this branch's base (dev), 24 streams each asked to end after a 2 s Go timer:

ended at 2 to 3 s still open at 15 s
dev, as it is 10 14
dev, delay rounded up 24 0

One caveat on that table: the program runs on workers-go, which ships its own copy of wasm_exec.js (it adds a context argument to run), so the rounding was applied to that copy, with dev's compiler and runtime. This PR's file itself was run under Node with a program of time.Sleep (1.5 ms and 250 ms), a time.Timer (100.3 ms), a context deadline (50 ms) and ten 10 ms ticks: 513 ms in all, against 510 ms before the change and 502 ms asked for.

On Cloudflare Workers the clock only advances by a timer's delay rounded
down to a whole millisecond. sleepTicks passed a fractional delay to
setTimeout, so when less than a millisecond was left the scheduler re-armed
a timer that never moved the clock, and Go timers (time.Sleep, time.Timer,
context deadlines) stalled until some other I/O happened.

Fixes tinygo-org#5798
@soypat

soypat commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Is this solving an issue with TinyGo or cloudflare workers? It kind of sounds like the latter. This also sounds like it could break users who depended on the current behaviour?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wasm: Go timers stall on Cloudflare Workers (runtime.sleepTicks passes fractional milliseconds to setTimeout)

2 participants